perm filename SOS.FAI[12T,LCS] blob
sn#028059 filedate 1975-11-19 generic text, type T, neo UTF8
TITLE SOS SON OF STOPGAP
IFNDEF TWOSGM,<↓TWOSGM←←1> ;DEFAULT TO TWO SEGMENTS.
SUBTTL DEFINITIONS
;TEMPORARY EDITOR FOR THE DISK--WORKS BY RECOPYING
;DEVICES USED
OPDEF TTYUUO [51B8]
OPDEF SLEEP [CALLI 31]
OPDEF GETPPN [CALLI 24]
OPDEF DATE [CALLI 14]
OPDEF TIMER [CALLI 22]
OPDEF MAIL [710B8]
OPDEF SEND [MAIL]
OPDEF PTYUUO [711B8]
OPDEF PTYGET [PTYUUO 0,]
OPDEF PTIFRE [PTYUUO 2,]
OPDEF PTWR1W [PTYUUO 7,]
OPDEF PTWRS7 [PTYUUO 11,]
OPDEF PTRD1W [PTYUUO 5,]
OPDEF PTYREL [PTYUUO 1,]
OPDEF JBTSTS [CALLI 400013]
IFNDEF TWOSGM,{↓TWOSGM←0}
↓STANSW←←1 ;ON FOR STANFORD TYPE PPNS, ETC
↓FULDPX←←1 ;FULL DUPLEX SCANNER
↓TTY←←1
↓IN←←2
↓OUT←←3
↓LPT←←4
↓ALTDV←←5 ;THE OTHER INPUT DEVICE (COPY AND TRANSFER)
;ACS USED
↓FL←10 ;FLAG REGISTER
↓T1←1 ;TEMP REGISTERS
↓T2←2
↓T3←3
↓T4←4
↓T5←5
↓FL2←11
↓ALTP←12 ;POINTER FOR ALTER MODE
↓CS←13 ;CHARACTER TABLE BITS
↓SINDEX←14 ;LINE TO FIND, USED ALSO BY THE VARIOUS ROUTINES
↓PNTR←15 ;POINTS AT CURRENT PLACE IN BUFFER
↓C←16 ;CHARACTER RETURNED HERE BY GNCH
↓P←17 ;PUSHDOWN LIST
;FLAGS (RIGHT HALF)
BOF←←1 ;NOW ON FIRST RECORD OF FILE
EOF←←2 ;HAVE READ END OF FILE BUT NOT NECESSARILY BUT IN BUFFER
EOF2←←4 ;LAST WORD OF FILE IS IN CURRENT BUFFER
ADDL←←10 ;USED IN COMMAND SCANNING--LINE NUMBER + INC
SUBL←←20 ;LINE NUMBER - INC
IDF←←40 ;SCAN HAS SEEN AN IDENTIFIER
NUMF←←100 ;SCAN HAS SEEN A NUMBER
TERMF←←200 ;SCAN SAW A TERMINATOR (LF OR ALTMODE)
LINSN←←400 ;THE COMMAND INPUT ROUTINES SAW A LINE NUMBER
PGSN←←1000 ;THEY SAW A PAGE NUMBER
NEWFL←←2000 ;NEW FILE NAME SEEN BY END CODE
ORDF←←4000 ;LINES OUT OF ORDER (USED BY NUMBER)
BGSN←←10000 ;BIGGEST PAGE HAS BEEN SEEN
M37F←←20000 ;THIS IS A MODEL 37
CNTF←←40000 ;COMMAND USING !
DPYF←←100000 ;THIS IS A III DISPLAY
READOF←←200000 ;THIS FILE IS BEING USED IN READ ONLY MODE
EXTOG←←400000 ;ON FOR SHORT ERROR MESSAGES
;FLAGS (LEFT HALF)
NEGF←←1 ;SEARCH HAS SEEN A ¬
DEMCHR←←2 ;SEARCH MUST SEE ANOTHER CHARACTER
ASSMF←←4 ;SEARCH HAS ASSUMED SEARCH CONTINUATION
ALTSRF←←10 ;HE WANTS TO DO A SEARCH AND EDIT
NUMSRF←←20 ;HE ONLY WANTS NUMBERS OF LINES FOUND
ARBITG←←40 ;WE ARE DOING ∞ CURRENTLY, DO NOT ALLOW ANOTHER
EXCTSR←←100 ;WANTS TO SEARCH EXACTLY (NOT IGNORE CASE)
COPFIL←←200 ;WE ARE COPYING FROM ANOTHER FILE
ISCOP←←400 ;WE ARE DOING A COPY
NOPRN←←1000 ;DO NOT PRINT WHILE DOING SUBSTITUTE
DECID←←2000 ;ALLOW USER TO DECIDE IF LINE IS OK
EXCTS1←←4000 ;ANOTHER EXACT SEARCH FLAG FOR SUBS
QMODF←←10000 ;DO NOT TREAT ? AS A SPECIAL CASE ON INPUT
GCOM←←20000 ;DOING A G COMMAND INSTEAD OF E
SRCOP←←40000 ;DOING A SEARCH OF SECOND FILE
TRANFL←←100000 ;THIS IS A TRANSFER COMMAND WHICH HAS DELETED LINES
TECOF←←200000 ;THIS IS A TECO FILE
FSTOPF←←400000 ;THIS IS THE FIRST READ OP ON THIS FILE
;FLAGS IN FL2 (RIGHT)
STARF←←1 ;WE HAVE SEEN A * FOR THE LAST LINE
RUBF←←2 ;WE ARE DOING RUBOUT IN INTRA-LINE EDIT
ALTDUP←←4 ;DUPLEX CHARACTERS IN ALTER MODE
RUBF2←←10 ;DOING DELETE TYPE RUBOUT IN ALTER MODE
SVIT←←20 ;WE ARE DOING A "W" COMMAND (SAVE WORLD)
JFFLG←←40 ;J DOES FILL ONLY
JRFLG←←100 ;J DOES RIGHT JUSTIFY
JCFLG←←200 ;J DOES CENTERING
JBLF←←400 ;J SEES A BLANK
SUPN←←1000 ;SUPPRESS LISTING OF LINE NUMBERS
JLFLG←←2000 ;J DOES LEFT JUSTIFY
JPER←←4000 ;J SEES A PERIOD OR SOMETHING LIKE IT
ZSRF←←10000 ;,Z IN SEARCH (ANALOGUE TO ,A -- SEE ALTSRF BIT)
ZSPA←←20000 ;TELLS ZLIN ROUTINE TO SPACE OUT
;BOTH THESE BITS SHOULD BE IN LH OF FL, BUT...
EXTERNAL JOBFF,JOBREL,JOBSYM,JOBDDT,JOBAPR,JOBSA,JOBOPC
OPDEF ERROR [1B8] ;ERROR UUOS FATAL ERROR
OPDEF NERROR [2B8] ;NON-FATAL ERROR
OPDEF RERROR [3B8] ;PRINT MESSAGE AND RETURN
;ERROR NUMBERS
ICN←←1 ;INTERNAL EDITOR CONFUSION
DIE←←2 ;DEVICE INPUT ERROR
DDE←←3 ;DEVICE OUTPUT ERROR
ILC←←4 ;ILLEGAL COMMAND
ILUUO←←5 ;PROTECTION. SOMEONE EXECUTED AN ILLEGAL UUO
LTL←←6 ;LINE IS TOO LOGNNG
NLN←←7 ;NULL COMAND RANGE
NSP←←10 ;NO SUCH PAGE (DELETE)
ORDER←←11 ;LINES OUT OF ORDER
UNA←←12 ;LPT NOT AVAILABLE FOR L COMMAND
ILR←←13 ;ILLEGAL REPLACEMENT WITH INSERT
WAR←←14 ;WRAP AROUND IN RENUMBERING
TMS←←15 ; TOO MANY SEARCH STRINGS GIVEN
STL←←16 ;TOO MANY TOTAL STRING CHRS
ISS←←17 ;ILLEGAL SEARCH STRING
ILFMT←←20 ;ILLEGAL LINE FORMAT DETECTED
NSG←←21 ;NO STRING GIVEN
FNF←←22 ;FILE NOT FOUND (COPY)
DNA←←23 ;DISK NOT AVAILABLE (COPY)
NEC←←24 ;NOT ENOUGH CORE (COPY)
IRS←←25 ;ILLEGAL REPLACEMENT STRING
STC←←26 ;SEARCH STRING TOO COMPLEX (GOT PDLOV)
ITD←←27 ;ILLEGAL TRANSFER DESTINATION (PLACE NO LONGER THERE)
NNN←←30 ;NO NEXT LINE (FROM JOIN TYPE COMMANDS)
BKO←←31 ;BREAK OUT BY ↑C-REENTER IF POSSIBLE
↓SRBLG←←=200 ;NUMBER OF CHRS ALLOWED IN SEARCH STRING
↓SRNUM←←6 ;NUMBER OF SEARCH STRINGS ALLOWED
↓PDLSIZ←←200 ;PUSHDOWN LIST SIZE
↓MXWPL←←=30 ;MAX NUMBER OF WORDS PER LINE
↓LSNUM←←3 ;NUMBER OF NESTED LINE SEARCHES ALLOWED
IFN STANSW,<%LPP←←=52>
IFE STANSW,<%LPP←←=58>
DEFINE IFEDUPL {IFE FULDPX, } ;MAKE CONDIT ASSEMBLIES EASIER
DEFINE ELSE {IFN FULDPX, }
DEFINE TERPRI (AC) {
IFEDUPL {MOVEI AC,[BYTE (7) 15,12]
CALLI AC,3 ;PRINT CR-LF
;} TTYUUO 3,[BYTE (7) 15,12]
}
DEFINE MSSG (AC,MX) {
IFEDUPL {MOVEI AC,[ASCIZ /MX/]
CALLI AC,3 ;} TTYUUO 3,[ASCIZ /MX/]
}
DEFINE MSG (AC,MX) {
IFEDUPL {MOVEI AC,[ASCIZ /
MX
/]
CALLI AC,3
} ELSE {TTYUUO 3,[ASCIZ /
MX
/]}
}
DEFINE MSGSTR (AC,MX) {
IFEDUPL {MOVEI AC,[ASCIZ /
MX
*/]
CALLI AC,3
} ELSE {TTYUUO 3,[ASCIZ /
MX
*/]}
}
; PRINT A MESSAGE -- GET A CHARACTER IN REPLY
DEFINE GTNS(MSG) <
IFE FULDPX ,<
MOVEI T1,[ASCIZ /MSG/]
CALLI T1,3
MOVEI T1,DDTINB
CALLI T1,1
LDB T1,[POINT 7,DDTINB,6]
>
IFN FULDPX,<
TTYUUO 3,[ASCIZ /MSG/]
TTYUUO T1
>
>
SUBTTL DATA AREA -- LOWER SEGMENT
Comment ⊗ DCS Here is all the data in the world, so arranged
as to be a template for the upper segment, the data for
the lower segment, and an example to the world. ⊗
DEFINE IFB (X) {IFIDN {X⎇{⎇ ⎇
DEFINE IFNB (X) {IFDIF {X⎇{⎇⎇
DEFINE DATA(WHAT,HOWM,STUFF) {
IFNB (WHAT) , {WHAT:⎇
IFNB (HOWM) , {HOWMANY←←HOWM;⎇ HOWMANY←←1
IFNB (STUFF), {STUFF;⎇ BLOCK HOWMANY
}
DATA (SCRUP1)
DATA (SCRUP2)
DATA (ACCUM) ;ACCUMULATE 6-BIT IN SCANNER
DATA (ALTBF,3)
DATA (ALTCNT) ;# CHARS TO POINTER IN ALTER MODE
DATA (ALTFLG) ;ON IF CR INSERTED IN ALTER MODE
DATA (ALTINC) ;LINE INCREMENT FOR ALTER MODE
DATA (ARBBUF,MXWPL*2+1)
DATA (ARBCNT)
DATA (BGPG) ;LARGEST PAGE NUMBER OF FILE
DATA (BLIN)
DATA (BOTLIN) ;LINE # PRECEDING LOWEST LINE TRANSFERRED
DATA (BPW)
DATA (BUFHD) ;→AFTER TTY BUFFERS, BEFORE DISK BUFFERS
DATA (BUFP) ;→WORKING BUFFER
DATA (BUFSAV)
DATA (CASEBT) ;FOR CASE TRANSLATIONS (←LOWER, ETC.)
DATA (CCNT)
DATA (CLN) ;"." LINE
DATA (CODEBF,4*SRNUM+2)
DATA (COPDL) ;SAVE PDL FOR ERRORS, WHEN IN FILE→FILE COPY
DATA (CORTOP) ;JOBREL AFTER WORKING BUFFER ALLOC
DATA (CPG) ;CURRENT PAGE CONTAINING (PNTR)
DATA (CPGL) ;"." PAGE
DATA (CURINS) ;LINE # TO INSERT IF NO "I" ARGUMENT
IFEDUPL,{
DATA (DDTINB,=25) ;DDT-INPUT BUFFER
}
DATA (DESTN)
DATA (DESTLN) ;DESTINATION IN COPY AND
DATA (DESTPG) ; TRANSFER COMMANDS
DATA (DPG) ;DESIRED PAGE FOR FIND
DATA (EDNAM) ;NAME OF FUNNY TEMP FOR RECOPY
DATA (ELIN)
DATA (ENDD) ;POINTER TO END OF SPECIAL COPY BUFFER
DATA (FILPT) ;END OF WORKING BUFFER (FOR FILLING)
DATA (FINCR) ;INCR1 FOR COPY
DATA (HIGH1)
DATA (HILN) ;LAST (OR ONLY) LINE OF CURRENT RANGE
DATA (HIPG) ; " FOR PAGE
DATA (HLFWC) ;HALF WRK BUF SIZE --USED TO DETERMINE ACTION IN DUMP
DATA (IBUF,3) ;INPUT BUFFER HEADER
DATA (INCR) ;INSERT/REPLACE INCREMENT
DATA (INCST)
DATA (INDNT)
DATA (INPG) ;PAGE BEING INPUT (FOR ORDER CHECKING)
DATA (IPG) ;CURRENT PAGE TO INSERT ON, IF NONE GIVEN
DATA (JFLOP,,=1) ;L/R JUSTIFICATION FLIP-FLOP
DATA (LIBUF,MXWPL+2) ;LINE INPUT AND ALTERATION BUFFER
DATA (,1,<BYTE (7)15,15,15,15,15>);MAKE SURE IT TERMINATES RIGHT
DATA (LIBUF2,MXWPL+2) ;FOR CR INSERT IN ALTER MODE
DATA (LINK)
DATA (LINL)
DATA (LINOUT)
DATA (,1,<ASCIZ ./.>)
DATA (LLHILN)
DATA (LLHIPG)
DATA (LLRCNT)
DATA (LLRPG)
DATA (LMAR,,1) ;LEFT MARGIN COLUMN SETTING
DATA (LOBUF,3)
DATA (LOGPG)
DATA (LOLN) ;FIRST LINE OF CURRENT RANGE
DATA (LOPG) ;FIRST PAGE OF SAME
DATA (LPTBUF,203*2+1)
DATA (LSBUFN)
DATA (LSBUF,<(SRBLG/5*2)*LSNUM>)
DATA (LSPNT,SRNUM*LSNUM)
DATA (LSTCNT)
DATA (LSTLN)
DATA (LSTPG) ;LAST PAGE # INSERTED IN COPY BUFFER
DATA (LWRD)
DATA (MAXLN,1,<ASCID /99999/>);MAX ALLOWABLE LINE #
DATA (MAXWC) ;MAX ALLOWABLE WC FOR WORKING BUFFER
DATA (MAXWL)
DATA (NAMI,4) ;INPUT LOOKUP BLOCK
DATA (NAMO,4) ;OUTPUT LOOKUP BLOCK
DATA (NCNT) ;CHAR CNT FOR NEW LINE (REPLAC OR INSERT)
DATA (NLIN1) ;#LINES ON FIRST PAGE (COPY)
DATA (NLIN2) ;" LAST "
DATA NORENT ;DON'T DO EMERGENCY FLUSH IF ON
DATA (OBUF,3) ;OUTPUT BUFFER HEADER
DATA (OCNT) ;CHAR CNT FOR OLD LINE (BEING REPLACED)
DATA (OCNT1)
DATA (OLDLIN) ;USED IN FILLBF FOR ORDER CHECKING
DATA (OPTR)
DATA (ORGEXT) ;ORIGINAL FILE
DATA (ORGNAM) ; NAME
DATA (ORGPPN) ; INFO
DATA (ORGPRO) ; "
DATA (PDL,PDLSIZ) ;PUSH DOWN LIST
DATA (PGDELS) ;#PAGES DELETED IN COPY/TRANSFER
DATA (PGHS,7,<ASCII / /
ASCII / /
BYTE (7) 40,40,40,40,15
ASCIZ /PAGE /
>)
DATA (PGHD,12) ;ALL FOR LPT OUTPUT
DATA (PGINSD)
DATA (PMAR,,1)
DATA (ASCZ1,,<ASCII /INC1=/>)
DATA (PRNTO1,2,<0
ASCIZ /
/>)
DATA (ASCIZ2,,<ASCII /INC2=/>)
DATA (PRNTO2,2,<0
ASCIZ /
/>)
DATA (REENTSW) ;FOR EMERGENCY EXITS
DATA (RENCNT) ;FOR PANIC MEASURES AT ENDIT TIME
DATA (REINC)
DATA (REM)
DATA (RMAR,,=69) ;RIGHT MARGIN COLUMN
↓MAXL←RMAR
DATA (RPCNT)
DATA (RPGSW) ;IF ON, READING COMMANDS FROM QQSVED.RPG
DATA (RPHILN)
DATA (RPHIPG)
DATA (RPPG)
DATA (RSTRCT)
DATA (RSW) ;/R TYPED IN COMMAND LINE
DATA (R1BUF,SRBLG/5+2)
DATA (R1PNT,SRNUM) ;"FOR" STRING POINTER
DATA (R2BUF,SRBLG/5+2)
DATA (R2PNT,SRNUM) ;"SUBSTITUTE" STRING POINTER
DATA (SAVC) ;SAVCHR FOR JUST/JOIN KLUDGE
DATA (SAVCHR) ;SAVCHR FOR SCANNER
DATA (SAVCNT) ;NO OF LINE-CHANGING OPERATIONS SINCE LAST "W"
DATA (SAVNUM) ;NO OF " BETWEEN "W"'S
DATA (ISVNUM) ;SAVNUM FOR INSERT MODE
DATA (ISVCNT) ;SAVCNT FOR INSERT MODE
DATA (INSSW) ;FOR INSERT MODE "W" FEATURE
DATA (SINCR) ;INCR2 FOR COPY
DATA (SQBUF,2,<0
ASCIZ / />) ;TAB-- FOR PRINTING LINE NUMBERS
DATA (SRBUF,SRBLG/5+2)
DATA (SRCALP)
DATA (SRCNT)
DATA (SRHILN)
DATA (SRHIPG)
DATA (SRPG)
DATA (SRPNT,SRNUM) ;SEARCH STRING POINTER
DATA (SSW) ;/S TYPED IN COMMAND LINE
DATA (STARTD) ;START OF DELETED CODE FOR TRANSFER
DATA (SVALTP) ;TMP FOR SAVING ALTP IN ALTER COMMAND
DATA (SVCCNT)
DATA (SVCNT) ;HOLDS ! ARG FOR COMMANDS
DATA (SVCRLC) ;TEMP BP HOLDER WHEN INSERTIN CR IN Z MODE
DATA (SVERN)
DATA (SVINC) ;INCR FROM LINE # (I.E., 500+1)
DATA (SVJRL) ;SAVE CORE ADDRESSES FOR
DATA (SVJRL2) ; RELEASE AFTER COPY COMMANDS
DATA (SVLNUM)
DATA (SVPT)
DATA (SVT1E) ;STORE T1 IN ERROR HANDLER
DATA (SVWD) ;WORD READ BUT NOT STORED BY FILLBF
DATA (SVWD2) ;FOR ORDER CHECKING IN FILLBF
DATA (SVWD3) ;TEMP IN DELETE
DATA (TCHR)
COMMENT /STUFF FOR SPOOLING LISTINGS/
DATA (SPOOLR)
DATA (OPENBK,4)
DATA (TIBUF,3) ;TTY INPUT BUFFER HEADER
DATA (TMPT1) ;RDTECO TEMP
DATA (TOBUF,3) ;TTY OUTPUT BUFFER HEADER
DATA (TPNT)
DATA (TRANST) ;PAGE ON WHICH DELETION STARTS (TRANSFER)
DATA (WC) ;CURRENT WORKING BUFFER WORD COUNT
DATA (WCNT)
DATA (WRDL)
DATA (WTBL,,<[1]>)
DATA (ZCOMMND) ;ON IF INSERTING CR IN Z MODE, OFF IF IN A
DATA (ZSW) ;USED TO CONTROL ALTER-XTEND COMMANDS
;(USE SYSTEM OR INTERNAL, ALTER OR XPAND)
SUBTTL TWO SEGMENT SOS INITIALIZATION CODE
LOC 124 ;SET UP RE-ENTER ADDRESS
REENT ;TO STOP SEARCHES AND SUBSTITUTES EARLY.
RELOC
Comment ⊗ DCS
Here is code to create a second segment (one time only), and
to attach to it (each time program is restarted). It just pokes
at the system in any number of different ways. ⊗
IFN TWOSGM,{
ERRHD: 0
JRST ERRHDA ;PUT UUO TRAP LOCATION IN LOWER SEGMENT
STPTA: TDZA T1,T1 ;NO RPG
MOVEI T1,1 ;RPGSW TO BE SET
ADDI T1,STPT ;THIS IS STARTING ADDRESS
HRRM T1,JOBSA ; BEFORE YOU FORGET IT
MOVEI 17,FRSTACS ;SAVE ORIGINAL VALUES
BLT 17,FRSTACS+16 ; BECAUSE THERE ARE FILE NAMES
; AND THINGS IN THERE
CHK2: CALLI 400023 ;LINKUP IF 2D SEGMENT THERE ALREADY
SKIPA ; NOT THERE, USE THIS COPY
JRST MOVSY ; THERE, MOVE SYMBOL TABLE DOWN AND COLLAPSE
MAK2: HRRZ T1,JOBSYM ;BY DEFINITION, END OF 2D SEGMENT CODE
SUBI T1,SEG2LOC ;T1 IS LENGTH OF 2D SEGMENT CODE
MOVE T2,T1 ;CORE2 PROBABLY CLOBBERS
CALLI T2,400015 ;CALL CORE2 TO MAKE A 2D SEGMENT
HALT ; SHOULD BE ABLE TO GET IT
HRRI T2,400000 ;DEST
HRLI T2,SEG2LOC ;SOURCE
BLT T2,400000-1(T1) ;MOVE 2D SEGMENT CODE UP
CALLI T1,36 ;WRITE-PROTECT 2D SEGMENT
HALT ;COULDN'T DO IT?
MOVSY: MOVEI T2,SEG2LOC
SKIPN JOBDDT
JRST MOVSY1
HLRE T3,JOBSYM ;-SYMBOL TABLE SIZE IN T3
HRL T1,JOBSYM ;BLT WORD FOR SYMBOLS IN T1
HRRI T1,SEG2LOC
HRRM T1,JOBSYM ;UPDATE JOBSYM
MOVNI T2,-SEG2LOC(T3) ;NEW END OF SYMBOLS ADDR IN T2
BLT T1,-1(T2) ;MOVE SYMBOLS DOWN
MOVSY1: HRRZ T1,T2 ;CORE CLOBBERS AC
CALLI T1,11 ; CUT DOWN TO REASONABLE 1ST SEGMENT SIZE
HALT ; BUT IT'S EASY!!
HRLM T2,JOBSA ; IT UP
CALLI ;TRANSFER TO JOBFF, CLEAR THE WORLD
GOEDIT: MOVSI 17,FRSTACS ;RESTORE ALL THE ORIGINAL
BLT 17,16 ; GOODIES
HRRZ T1,JOBSA ;STARTING ADDRESS
JRST (T1)
FRSTACS: BLOCK 17 ;SAVE ORIGINAL ACS HERE FOR A WHILE
SEG2LOC:
PHASE 400000 ;PUT ALL ELSE IN UPPER SEGMENT
}
SUBTTL REENTER-ER, RPG SWAPPER -- BEGINNING OF SEGMENT 2
REENT: SETOM REENTSW ;JUST FLAG AND CONTINUE
JRST @JOBOPC
CREFIT: IFE FULDPX,<MOVEI T1,[ASCIZ /
/]
CALLI T1,3>
IFN FULDPX,<TTYUUO 3,[ASCIZ /
/]>
MOVEI T1,RPGR
CALL T1,[SIXBIT /SWAP/]
CALLI 12
RPGR: SIXBIT /SYS/
SIXBIT /RPG/
0↔1↔0
SUBTTL INITIALIZATION
;HERE IS THE INITIALIZE CODE
STPT: SKIPA
JRST [SETOM RPGSW ;IN RPG MODE
SOS JOBSA ;REST START
MOVEM 14,ORGNAM ;SAVE NAME
MOVEM 14,NAMI
HLLZM 13,ORGEXT
HLLZM 13,NAMI+1
MOVEM 11,ORGPPN
MOVEM 11,NAMI+3
IFE STANSW,<MOVSI FL,QMODF>
IFN STANSW,<MOVEI FL,0>
MOVEI FL2,0
MOVEM 15,HILN ;LINE NUMBER
MOVEM 15,LOLN ;SET UP TO PRINT (FOR SAIL ETC)
MOVEM 16,HIPG ;AND PAGE NUMBER
MOVEM 16,LOPG
MOVEI C,0
TRNE 13,400000 ;CREATE MODE?
MOVEI C,200
TRNE 13,200000
TRO FL,READOF ;SET FOR READ ONLY
JRST RPGRET]
SETZM RPGSW
CALLI
IFN STANSW,< MOVEI FL,0 ;CLEAR FLAG REGISTER>
IFE STANSW,< MOVSI FL,QMODF ;SET FOR ? IS NOT SPECIAL>
MOVEI FL2,0 ;CLEAR SECOND FLAG REGISTER
RPGRET: MOVE T1,[JSR ERRHD] ;SET UP UUO HANDLER
SETOB 0,SCRUP2 ;THIS BETTER NOT CHANGE.
MOVEM T1,41
CALLI T1,14
IDIVI T1,=372
MOVEI T1,=25
MOVEM T1,SCRUP1
CAIE T2,=93
SETZM SCRUP2
MOVEI T1,PDLOV ;SET UP A PDLOV TRAP
MOVEM T1,JOBAPR
MOVEI T1,200000 ;SET FOR PDLOV ONLY
CALLI T1,16 ;APRENB
IFN FULDPX,<IFN STANSW,<INIT TTY,401 ;NO DUPLEX BUCKY BITS>
IFE STANSW,<INIT TTY,1 ;SET UP TTY FOR NO ALTMODE DUPLEXING>>
IFE FULDPX,< INIT TTY,401>
SIXBIT /TTY/
XWD TOBUF,TIBUF
CALLI 12 ;LOSE BIG
INIT IN,14
SIXBIT /DSK/ ;DISK FOR INPUT AND OUTPUT
XWD 0,IBUF
JRST NODSK
INIT OUT,14
SIXBIT /DSK/
XWD OBUF,0
JRST NODSK ;WE ARE IN TROUBLE
INBUF TTY,2
OUTBUF TTY,2 ;SET UP TELETRIPE BUFFERS
MOVE T1,JOBFF ;NOW SAVE JOBFF
MOVEM T1,BUFHD ;FOR LATER RECOPY OPERATIONS
INBUF IN,2 ;GET DISK BUFFERS SET UP
OUTBUF OUT,2
MOVE T1,JOBFF
SETZM (T1) ;SAVE A ZERO WORD
ADDI T1,1 ;NEXT ONE STARTS
MOVEM T1,BUFP ;START OF THE BUFFER
SKIPN T1,SAVNUM ;# LINE-CHANGING OPERATIONS BETWEEN "W"'S
HRLOI T1,377777 ;INITIALIZE TO BIG NUMBER
MOVEM T1,SAVNUM
MOVEM T1,SAVCNT ;ALSO INITIALIZE COUNTER
SKIPN T1,ISVNUM ;SIMILARLY FOR INSERT MODE COUNTS
HRLOI T1,377777
MOVEM T1,ISVNUM
MOVEM T1,ISVCNT
MOVE P,[IOWD PDLSIZ,PDL]
TRNN FL2,SVIT ;SKIP * IF DOING W COMMAND
SKIPE RPGSW
JRST RPGR1
MSSG (T1,<
FILE=>) ;PRINT THE FILE=
SUBTTL FILE NAME SCANNER
PUSHJ P,SCAN
PUSHJ P,READNM ;GET A FILE NAME
JRST ILFN ;ILLEGAL FORMAT
SKIPE SSW ;CHECK FOR AN S SWITCH
JRST ILFN
MOVE T1,NAMI
MOVEM T1,ORGNAM
MOVE T1,NAMI+1
MOVEM T1,ORGEXT
MOVE T1,NAMI+3
MOVEM T1,ORGPPN
SKIPE RSW ;ON IF /R
TRO FL,READOF
CKTRM2: TRNN FL,TERMF ;IS IT A TERMINATOR?
CAIN C,200 ;OR ALTMODE
JRST .+2 ;YES, WE'RE OK
JRST ILFN
RPGR1: SETZM NAMO
MOVE T1,[XWD NAMO,NAMO+1]
BLT T1,NAMO+3
IFE STANSW, <
CALLI T1,14 ;GET CURRENT DATE
CALLI T2,22 ;AND TIME IN TICKS
LSH T1,=21 ;USE TO MAKE A STRANGE NAME
IOR T1,T2
>;NOSTANSW
IFN STANSW, <;MAKE UP NAME BASED ON JOB NUMBER
CALLI T1,30 ;PJOB
IDIVI T1,=10 ;TEN'S PLACE IN T1, ONE'S PLACE IN T2
LSH T1,6
IOR T1,T2
IOR T1,['$ED$00'] ;JOB NUMBER IS PART OF EDIT NAME
>;STANSW
MOVEM T1,EDNAM ;SAVE FOR LATER
MOVEM T1,NAMO
MOVSI T1,'TMP'
MOVEM T1,NAMO+1
MOCO: MOVE T1,JOBREL ;FIND THE END OF CORE
MOVEM T1,CORTOP
SUBI T1,2*MXWPL+2 ;LEAVE SPACE FOR A COUPLE OF LINES
MOVEM T1,FILPT ;THIS IS HOW FAR TO FILL THE BUFFER
MOVE T1,CORTOP ;NOW FIND THE SIZE
SUB T1,BUFP
CAIGE T1,3000
JRST [MOVE T2,JOBREL
ADDI T2,2000
CALLI T2,11
SKIPA
JRST MOCO
JRST .+1] ;DID NOT GET IT, GIVE UP
MOVE T2,T1 ;GET A COPY
SUBI T2,MXWPL+1 ;WHEN TO START DUMPING
MOVEM T2,MAXWC
ASH T1,-1 ;TAKE HALF OF IT
MOVEM T1,HLFWC ;SAVE THAT FIGURE
TRNE FL2,SVIT
JRST NOSV1 ;SKIP SOME MORE STUFF IF IN W COMMAND
IFN STANSW,<
IFE FULDPX,<
CALL T1,[SIXBIT /GETLIN/] ;GET LINE NUMBERS FOR THIS TTY
LDB T2,[POINT 6,T1,23] ;THE DPYS ARE 20-25
CAIE T2,'2' ;SO THIS SHOULD BE A 2
JRST NODPY
LDB T2,[POINT 6,T1,29]
JUMPE T2,NODPY ;NO IT WAS TTY2
CAIG T2,'5' ;OR HIGHER THAN 25>
IFN FULDPX,<MOVNI T1,1 ;SET NEG TO GET OWN LINE
TTYUUO 6,T1 ;GET LINE CHARACTERISTICS
TLNE T1,420000 ;THE HIGH ORDER BIT SAYS ITS A DPY>
TRO FL,DPYF ;IT IS A DPY, SET IT UP>
TLNE T1,12000 ;IS IT AN M37, OR AN IMLAC.
TRO FL,M37F ;SET FLAG.
NODPY: MOVE T1,[ASCID /00000/]
MOVEM T1,CLN ;SET UP THE CURRENT LINE
MOVE T1,[ASCID /00100/] ;AND CURRENT INCREMENT
MOVEM T1,INCR
MOVEM T1,CURINS ;CURRENT PLACE TO INSERT IF NO ARGS TO I
NOSV1: MOVEI T1,1 ;AND THE CURRENT PAGE
MOVEM T1,CPG
TRNE FL2,SVIT ;DO NOT CHANGE LOGICAL PAGE (.)
JRST .+3
MOVEM T1,CPGL
MOVEM T1,IPG ;CURRENT PAGE TO INSERT ON
MOVE PNTR,BUFP ;SET THE BUFFER POINTER
MOVEI T1,1 ;SET INPUT PAGE
MOVEM T1,INPG
SETZM SVWD ;O WORDS WAITING
SETZM WC ;ZERO WORD COUNT FOR START
SETZM OLDLIN ;UESD FOR ORDER CHECKING ON INPUT
TRNE FL2,SVIT
JRST NOSV2
SETZM CASEBT ;0 FOR LETTERS AS UPPER CASE 40 FOR LOWER
SETZM SRPNT ;NO SEARCH STRING YET
SETZM R1PNT ;ALSO REPLACE STRINGS
SETZM R2PNT
CAIN C,200 ;IS IT ALTMODE
JRST CREAT
MOVSI T1,1 ;SET BIG PAGE LARGE FOR NOW
MOVEM T1,BGPG
NOSV2: LOOKUP IN,NAMI
JRST NOFIL ;IT IS NOT THERE
HLLZ T1,NAMI+2 ;GET PROTECTION.
TLZ T1,777 ;AND ONLY THAT.
MOVEM T1,ORGPRO ;TO MEM.
TRNE FL,READOF
JRST NOENT ;DO NOT ENTER
LOOKUP OUT,NAMO ;SEE IF EDIT WAS FLUSHED SOMEHOW
JRST TMPENT ;NO, FILE IS VIRGIN
CLOSE OUT, ;DON'T ENTER EXTEND MODE
SKIPN NAMO+3 ;LOOK FOR THE FILE LENGTH
JRST TMPENT ;ZERO LENGTH FILE. FLUSH IT
MSGSTR (T1,<TEMPORARY EDIT FILE ALREADY EXISTS! DELETE?(Y OR N)>)
PUSHJ P,FILEX1 ;GET THE ANSWER
CALLI 12 ;LET HIM DO SOMETHING TO KEEP IT
TMPENT: SETZM NAMO+3 ;CLEAR AGAIN
ENTER OUT,NAMO
JRST EDFLIN ;SOME OTHER BASTARD IS USING IT
NOENT: TRO FL,BOF ;IS AT START OF FILE
TLO FL,FSTOPF ;FIRST OP
PUSHJ P,FILLBF ;AND FILL UP THE BUFFER
SKIPE RPGSW ;IF NOT RPG
SKIPN HILN ;OR NO LINE PASSED
JRST COMND ;GET A COMMAND AND DO IT
JRST RPGPRN ;ELSE FORCE A PRINT COMMAND
SUBTTL CREATE A FILE
;CREATE A NEW FILE
CREAT: SETZM ORGPRO ;DEFAULT PROTECTION IS GOOD FOR YOU.
LOOKUP IN,NAMI ;SEE IF THERE IS ONE OF THAT NAME
JRST CRTOK ;NO, ALL IS WELL
SETZM RPGSW ;SO CRLF AFTER Y WILL PRINT
PUSHJ P,FILEXST ;TELL HIM FILE EXISTS, GET DISPENSATION
JRST STPT ;HE SAID "NO", START ALL OVER
;HE SAID "YES", GO AHEAD
CRTOK: LOOKUP OUT,NAMO ;SEE IF TEMP FILE WAS NOT RENAMED
JRST TMPENC ; IT'S ALL RIGHT (SEE ABOVE)
SKIPN NAMO+3
JRST TMPENC ;NO HASSLE FOR EMPTY TEMP FILE
CLOSE OUT, ;DON'T ENTER EXTEND MODE
MSGSTR (T1,<TEMPORARY EDIT FILE ALREADY EXISTS! DELETE? (Y OR N)>)
PUSHJ P,FILEX1 ;FIND OUT WHAT HE WANTS TO DO
CALLI 12 ;RECONSIDER
TMPENC: SETZM NAMO+3 ;ZERO PPN YET AGAIN
ENTER OUT,NAMO ;GO DO THE OUTPUT
JRST EDFLIN ;FOOBAZ
SETZM (PNTR) ;ZERO FIRST WORD OF BUFFER
TRZ FL,READOF ;CREAT AND READOF ARE NOT POSSIBLE
TRO FL,BOF!EOF!EOF2 ;SAY AT START AND NO MORE TO READ
MOVEI T1,1 ;SET BGPG
MOVEM T1,BGPG
IFEDUPL {MOVEI T1,[0]} ;PRINT NOTHING IF RPGSW
SKIPE RPGSW ;SHOULD WE PRINT?
JRST CRTINS ;NO, GO INSERT LINE 100 (OR SO)
TERPRI (T1) ; YES, DO CRLF
JRST COMND ;AT LAST
SUBTTL READ A FILE NAME
READNM: SETZM NAMI
MOVE T1,[XWD NAMI,NAMI+1]
BLT T1,NAMI+3 ;CLEAR AREA
SETZM RSW ;AND SWITCH FLAGS
SETZM SSW
TRNN FL,IDF!NUMF ;IS IT AND IDENT
POPJ P, ;ERROR RETURN
MOVE T1,ACCUM
MOVEM T1,NAMI
PUSHJ P,SCAN
CAIN C,"[" ;CHECK FOR PPN
JRST SETPPN
CAIE C,"."
JRST CKTERM
PUSHJ P,SCAN ;THIS SHOULD BE AN EXTENSION
TRNN FL,IDF!NUMF
POPJ P,
MOVE T1,ACCUM ;GET IT
HLLZM T1,NAMI+1 ;AND PUT IT IN THE EXTENSION FIELD
PUSHJ P,SCAN
CAIE C,"[" ;NOW LOOK FOR PPN
JRST CKTERM
SETPPN: PUSHJ P,SCAN
TRNN FL,IDF!NUMF
POPJ P,
PUSHJ P,RJUST ;RIGHT JUSTIFY IT
IFE STANSW,< POPJ P, ;NON-SKIP RETURN IF NOT OCTAL>
HRLZM T1,NAMI+3
PUSHJ P,SCAN
CAIE C,","
POPJ P,
PUSHJ P,SCAN
TRNN FL,IDF!NUMF
POPJ P,
PUSHJ P,RJUST
IFE STANSW,< POPJ P, ;LOSE>
HRRM T1,NAMI+3
PUSHJ P,SCAN
CAIE C,"]"
POPJ P,
PUSHJ P,SCAN
CKTERM: CAIE C,"/" ;CHECK FOR READ ONLY MODE
JRST CPOPJ1 ;ALL OK
PUSHJ P,SCAN
TRNN FL,IDF
POPJ P,
MOVS T1,ACCUM
CAIN T1,'R '
SETOM RSW
CAIN T1,'S '
SETOM SSW
PUSHJ P,SCAN
SKIPN RSW
SKIPE SSW
AOS (P)
POPJ P,
SUBTTL PPN JUSTIFIER, FILE CONFLICT HANDLER
IFN STANSW,<
RJUST: MOVE T1,ACCUM
RJUST1: TRNE T1,77 ;IS THERE ANYTHING THERE?
POPJ P, ;YES, IT IS RIGHT JUSTIFIED IN LEFT HALF
LSH T1,-6 ;MOVE IT OVER
JRST RJUST1 ;WE KNOW THERE IS SOMETHING THERE>
IFE STANSW,<
RJUST: MOVE T3,ACCUM ;GET THE SIXBIT
MOVEI T1,0
RJUST1: MOVEI T2,0
LSHC T2,6
CAIL T2,'0' ;CHECK FOR OCTAL DIGIT
CAILE T2,'7'
POPJ P,
LSH T1,3
IORI T1,-'0'(T2)
JUMPN T3,RJUST1 ;DONE IF NULLS LEFT
AOS (P)
POPJ P, ;SKIP RETURN FOR ALL OK>
; TELL USER FILE EXISTS
; ASK HIM WHAT HE WANTS TO DO ABOUT IT
; GET HIS ANSWER
; ACT ACCORDINGLY
FILEXST:
MSGSTR (T1,<FILE ALREADY EXISTS! DELETE? (Y OR N)>)
FILEX1:
BACK: IFEDUPL {
MOVEI T1,DDTINB
CALLI T1,1 ;GET ANSWER
LDB T1,[POINT 7,DDTINB,6] ;TO T1
;} TTYUUO 0,T1 ;MUCH EASIER WITH FULDPX
ANDI T1,177 ;TURN OFF BUCKY BITS
CAIN T1,"Y" ;YES, DELETE IT
JRST CPOPJ1 ; (SKIP RETURN)
CAIN T1,"N" ;NO, DON'T DELETE IT
POPJ P, ; (NON-SKIP RETURN)
; THERE ARE NO OTHER POSSIBILITIES
MSGSTR (T1,TYPE Y OR N)
JRST BACK
PGMK: ASCID / /
SUBTTL COMMAND DISPATCHER
;HERE IS THE COMMAND DECODER AND DISPATCHER
COMND: SETZM SAVCHR ;SCAN SHOULD GET RESET AT THIS POINT
SETZM REENTSW ;WAS USED TO STOP A SUBSTITUTE OR SEARCH
IFN FULDPX,<IFN STANSW,<SETSTS TTY,401>
IFE STANSW,<SETSTS TTY,1 ;JUST IN CASE DUPLEXING IS OFF>>
TLNE FL,SRCOP ;THIS CASE IS SPECIAL SINCE WE
SKIPA P,COPDL ;SHOULD NOT DESTROY SAVED ITEMS
MOVE P,[IOWD PDLSIZ,PDL] ;ALSO PDL (IN CASE OF ERRORS)
TLNE FL,SRCOP ;DOING SECOND FILE SEARCH?
JRST NOCPCK ;DO NOT GET OUT OF COPY MODE
TLZE FL,ISCOP ;IN COPY MODE?
JRST COPDON ;YES, DO SPECIAL CLEAR OUT
NOCPCK: MOVEI T1,[0] ;DON'T PRINT IF SUPN
TRNN FL2,SUPN ;SUPPRESS * AFTER PRETTY PRINT
MSSG (T1,*) ;PRINT A STAR
SETZM TIBUF+2
TRZ FL2,SVIT!SUPN ;MAKE SURE THAT THIS GETS TURNED OFF
MOVEI T1,LSNUM ;RESET LINE SEARCH STRINGS
MOVEM T1,LSBUFN
ICHK: MOVN T1,INSSW ;CHECK INSERT MODE SAVE REQUEST
JUMPE T1,CHKW ;NO SUCH REQUEST
MOVEM T1,INSSW ;UPDATE
JUMPG T1,DOW ;WANT TO SAVE
SETZM INSSW ;RESUME INSERT MODE
MOVEI T1,[BYTE (7) "I",15,12]
JRST DOI
CHKW: TRNN FL,READOF ;DON'T SAVE IF READ ONLY MODE
SKIPLE SAVCNT
JRST CMND1 ;OR IF NOT TIME YET
DOW: MOVE T1,SAVNUM
MOVEM T1,SAVCNT
MOVE T1,ISVNUM ;RESET THESE
MOVEM T1,ISVCNT
MSG (T1,<SAVING>)
MOVEI T1,[BYTE (7) "W",15,12]
DOI: HRLI T1,440700 ;A GOOOD BYTE POINTER
MOVEM T1,TIBUF+1 ;FOOL GNCH
MOVEI T1,4 ;WILL GET THREE CHARS
MOVEM T1,TIBUF+2
CMND1: PUSHJ P,GNCH ;READ A CHARACTER
CAIE C,15
JUMPE CS,CMND1 ;IGNORE SPACES ETC
TLNE CS,LETF⊗16 ;CHECK TO SEE IF LETTER
TRZ C,40 ;AND CONVERT TO UPPER CASE
MOVSI T1,-CMDLG ;GET LENGTH OF COMMAND TABLE
CAME C,CMD1(T1) ;COMPARE
AOBJN T1,.-1 ;CHECK FOR MATCH
SKIPGE CMD2(T1) ;DOES THIS COMMAND PERHAPS CHANGE THINGS?
SOS SAVCNT ;YES, COUNT SUCH COMMANDS
JUMPL T1,@CMD2(T1) ;DISPATCH IF FOUND
NERROR ILC ;ELSE ERROR
CMD1: "W"↔"G"↔"E"↔"I"↔"D"↔"R"↔"J"
"A"↔"Z"↔"X"↔"Q"↔"N"↔12↔200↔"F"↔"S"↔"M"↔"C"
"T"↔"P"↔"L"↔"←"↔"="↔15
CMDLG←←.-CMD1
DEFINE CG(A) <XWD 400000,A> ;THIS COMMAND CHANGES THINGS
CMD2: SVCOD↔GEND↔ENDIT↔CG(INSERT)↔CG(DELETE)↔CG(REPLAC)↔CG(JUST)
CG(ALTER)↔CG(ZALT)↔CG(XPAND)↔CG(QPAND)↔CG(NUMBER)↔NXTLIN
BAKLIN↔SEARCH↔CG(SUBST)↔CG(MARK)↔CG(COPY)
CG(TRANS)↔PRINT↔0+LIST↔0+SET↔GIVE↔COMND
SUBTTL END OF EDIT CODE (THIS IS THE DANGEROUS PART!)
BEGIN ENDIT
;CODE TO FINISH OFF EDIT
↑SVCOD: TRO FL2,SVIT ;SET TO DO A SAVE
JRST END0
↑GEND: TLOA FL,GCOM ;GO
↑ENDIT: TLZ FL,GCOM ;NORMAL TYPE END
END0: TLNE FL,SRCOP
JRST DSCOP ;FINISH UP THE COPY COMMAND
TRNE FL,READOF ;IF READ ONLY
JRST ENDEN2
TRZ FL,NEWFL ;SET TO WANTS SAME OLD PROGRAM
MOVE T1,ORGNAM ;GET THE ORIGINAL NAME
MOVEM T1,NAMI ;GET SET UP
MOVE T1,ORGEXT ;AND EXTENSION
HLLZM T1,NAMI+1
PUSHJ P,NSCAN ;GET A NAME
NERROR ILC ;SKIPS IF NO ERRORS
PUSHJ P,OCOMPL ;FINISH COPY
CLOSE IN,0 ;AND CLOSE FILES
CLOSE OUT,0
END7: SETZM NAMI+3 ;ZERO PPN
LOOKUP IN,NAMI ;GET IT
JRST END3 ;NO WORRY
TRNN FL,NEWFL ;IS THIS A NEW FILE?
JRST END4 ;NO, WE SHOULD HAVE FOUND IT
PUSHJ P,FILEXST ;TELL USER IT EXISTS, GET DISPENSATION
JRST END8 ; DON'T DELETE IT
; DELETE OLD COPY
END4: SETZM NAMI ;DELETE THE LOSER
SETZM NAMI+3
END3:
END5: SETOM RENCNT
END66: MOVE T1,EDNAM ;GET THE OUTPUT
MOVEM T1,NAMO
MOVSI T1,(<SIXBIT /TMP/>)
MOVEM T1,NAMO+1
SETZM NAMO+3
LOOKUP OUT,NAMO
JRST EDFLIN ;GIVE UP
MOVE T1,ORGNAM ;SET TO DESIRED NAME
MOVEM T1,NAMO
MOVE T1,ORGEXT
MOVEM T1,NAMO+1
MOVE T1,ORGPRO ;PROTECTION.
MOVEM T1,NAMO+2
SETZM NAMO+3
SKIPE NAMI ;DO WE WANT TO DELETE OLD FIRST?
JRST NORENI ; NO, NEW NAME
RENAME IN,NAMI ;DELETE OLD FILE AT LAST MINUTE POSSIBLE
JRST FIU ;SOMETHING BAD HAPPENED
NORENI: RENAME OUT,NAMO
AOSA T1,RENCNT ;FAILED, SEE HOW BAD IT IS
JRST ENDEND ;OK, GO FINISH UP
JUMPG T1,ENDEN1 ;BAD, PANIC.SOS EXISTS ALREADY, KEEP TEMP
TRZ FL,NEWFL
SETOM NAMI ;DON'T DO RENAME AGAIN
CLOSE IN,
CLOSE OUT, ;CLEAR THE WORLD
MOVE T1,['PANIC '] ;DEFAULT FILE WHEN THINGS GO WRONG
MOVEM T1,ORGNAM ;CAN'T USE ORIG NAME AGAIN IN ANY CASE
MOVSI T1,'SOS'
MOVEM T1,ORGEXT
SETZM ORGPRO ;DONT PROTECT HIM.
JRST END66 ;TRY ONCE MORE TO GET A TYPABLE NAME
; FILE BAD, AND PANIC.SOS STILL EXISTS
ENDEN1: MSSG (T1,<SOMEONE IS READING YOUR FILE.
PANIC.SOS ALREADY EXISTS.
SO YOU CAN FIND YOUR EDITED TEXT ON FILE >)
MOVE T2,EDNAM ;PRINT OUT NAME OF EDIT TEMP FILE
PRTSIX: MOVEI T1,0
LSHC T1,6 ;SIXBIT TO T1
ADDI T1,40 ;ASCII TO T1
TTYUUO 1,T1 ;TYPE IT IF FULDPX, ELSE LOSE
JUMPN T2,PRTSIX
MSSG (T1,<.TMP -- SORRY.
>)
JRST ENDEN2 ;WE'VE DONE THE BEST WE CAN
ENDEND: SKIPL RENCNT ;DID ALL GO WELL?
MSG (T1,<SOMEONE IS READING YOUR FILE.
SO YOU CAN FIND YOUR EDITED TEXT ON FILE PANIC.SOS -- SORRY.>)
ENDEN2:
CLOSE OUT,0
RELEASE OUT,0
CLOSE IN,0
RELEASE IN,0
TRNE FL2,SVIT
JRST [CALLI
SETZM RPGSW ;RESET ALL THE GOOD JUNK
TLZ FL,TECOF
TRZ FL,BOF!EOF!EOF2
TRNN FL,READOF
SETZM ORGPPN
MOVE T1,ORGNAM
MOVEM T1,NAMI
MOVE T1,ORGEXT
MOVEM T1,ORGPPN
JRST RPGRET] ;AND GO
TLNN FL,GCOM
CALLI 12
JRST CREFIT
NSCAN: PUSHJ P,SCAN ;SEE IF HE WANTS TO GIVE IT A NEW NAME
TRNE FL,TERMF ;TERMINATOR?
JRST CPOPJ1 ;DO SKIP RETURN
PUSHJ P,READNM ;GET A FILE NAME
POPJ P,
SKIPN RSW
SKIPE SSW ;SWITCHES ILLEGAL
POPJ P,
SKIPN NAMI+3 ;ALSO PPN
TRNN FL,TERMF
POPJ P,
TRO FL,NEWFL
MOVE T1,NAMI ;SET AS NAME
MOVEM T1,ORGNAM
MOVE T1,NAMI+1
MOVEM T1,ORGEXT
JRST CPOPJ1
END8: MSSG (T1,<
*>)
END6: SETZM SAVCHR ;GET A NEW NAME. RESET SCAN
SETZM TIBUF+2
PUSHJ P,NSCAN
SKIPA
JRST END7
MSGSTR (T1,<?????>)
JRST END6 ;YOU'RE GOING TO DO IT OVER AND OVER UNTIL
;YOU GET IT RIGHT
FIU: MSGSTR (T1,<FILE IN USE OR WRITE PROTECTED. TRY ANOTHER NAME>)
JRST END6
INFCNF: MSG (T1,<THERE IS INFINITE CONFUSION. YOU LOSE.>)
CALLI 12
BEND ENDIT
SUBTTL INSERT ROUTINE
BEGIN INSERT
;INSERT A LINE
↑CRTINS:MOVEI T1,1 ;SET UP TO START INSERTING AT LINE 100 PAGE 1
MOVEM T1,HIPG
MOVE T1,[ASCID /00100/]
MOVEM T1,HILN
JRST INSGO ;AND AWAY WE GO
↑INSERT:PUSHJ P,SCAN
TRNE FL,TERMF ;CHECK FOR NO ARGUMENTS
JRST [MOVE T1,IPG
MOVEM T1,HIPG
MOVE T1,CURINS
MOVEM T1,HILN
JRST INSGO] ;GO BACK TO INSERTING WHERE YOU WERE
PUSHJ P,GET1 ;GET ONE LINE/PAGE NUMBER
TRNN FL,READOF ;ERROR IF READ ONLY MODE
TRNN FL,LINSN ;WAS A LINE NUMBER SEEN
NERROR ILC ;ERROR IF NOT
CAIE C,"," ;IF A COMMA, SET INCREMENT
JRST NOINC ;NO, KEEP OLD ONE
PUSHJ P,SCAN ;GET THE NUMBER
TRNE FL,NUMF ;WAS IT A NUMBER?
CAMN T1,[ASCID /00000/] ;DO NOT PERMIT 0 INCR
NERROR ILC ;HE WAS CONFUSED
MOVEM T1,INCR ;SET INCREMENT
PUSHJ P,SCAN ;SCAN PAST IT
NOINC: TRNN FL,TERMF ;TERMINATOR?
NERROR ILC ;LOSE
INSGO: MOVE T1,HIPG ;GET THE PAGE TO GO TO
MOVEM T1,DPG ;AND SET IT UP
MOVE SINDEX,HILN ;ALSO LINE
PUSHJ P,FIND ;GO GET UM
MOVE T2,CPG ;DEMAND CORRECT PAGE MATCH
CAME T2,HIPG
NERROR NSP
CAMN T1,HILN ;ARE THEY MATCHING?
JRST FIXINL ;GO MAKE UP A LINE NUMBER
INSLP: SETZM OCNT
SOSG ISVCNT ;TIME TO SAVE THE WORLD?
JRST SVINS ;YES, SAVE AND RE-INSERT
MOVE T1,HILN ;TELL HIM THE LINE HE IS INSERTING
MOVEM T1,LIBUF ;AND PUT IT IN THE BUFFER
PUSHJ P,OUTSN ;PUT IT OUT
PUSHJ P,RDLIN ;READ A LINE
JRST LVINS ;YES, GET OUT OF INSERT MODE
MOVEM T1,NCNT ;HERE IS THE COUNT OF THE NEW ONE
PUSHJ P,INSED ;GO INSERT
PUSHJ P,FINDN ;MOVE UP A LINE
PUSHJ P,FILLB ;AND DUMP SOME IF NECESSARY
MOVE T1,CPG ;SET CURRENT LINE AND PAGE TO LAST
MOVEM T1,CPGL ;ONE REALLY INSERTED
MOVE T1,HILN
MOVEM T1,CLN
MOVE T2,INCR ;GET NEXT LINE TO INSERT
PUSHJ P,ASCIAD
CAMG T1,INCR ;HAVE WE WRAPED AROUND
JRST COMND ;YES, STOP
MOVEM T1,HILN ;STORE FOR REFERENCE
↑ENTINS:SKIPN T1,(PNTR) ;GET THE LINE POINTED TO
JRST INSLP ;ALWAYS INSERT AT END OF FILE
CAME T1,PGMK ;OR AT END OF PAGE
CAMLE T1,HILN ;HAVE WE FOUND A MATCH OR PASSED OVER A LINE?
JRST INSLP ;NO, INSERT
JRST COMND ;RETURN TO COMMAND
SVINS: SETOM INSSW ;MARK FOR "W","I" PAIR
LVINS: MOVE T1,HILN
MOVEM T1,CURINS ;SET PLACE TO INSERT NEXT TIME
MOVE T1,CPG
MOVEM T1,IPG
↑LEVINS:
TERPRI (T1) ;GIVE HIM SOMETHING SO * NOT ON SAME LINE
JRST COMND
FIXINL: MOVE T2,INCR ;SET TO ADD INCR
PUSHJ P,ASCIAD ;ADD
PUSH P,T1 ;SAVE RESULT
PUSHJ P,FINDN ;GET THE NEXT ONE
POP P,T2
CAMG T2,HILN ;IS THERE A WAR PROBLEM
JRST INCBAD ;YES, WE MUST TRY TO COMPUTE ONE
JUMPE T1,INCOK ;END OF FILE, ANY INC IS OK
CAME T1,PGMK ;ALSO OK IF A PAGE MARK
CAMGE T2,T1 ;OR IN CORRECT ORDER
JRST INCOK
INCBAD: CAME T1,PGMK
SKIPN T1
MOVE T1,[ASCID /9999:/] ;ONE OVER THE TOP OF THE WORLD
MOVE T2,HILN ;GET CURRENT
PUSHJ P,ASCAV ;FIND AVERAGE
CAME T2,HILN ;THERE MAY HAVE ONLY BEEN A DIF OF 1
JRST INCOK ;ALL IS WELL
NERROR ILR
INCOK: MOVEM T2,HILN
JRST INSLP
BEND INSERT
SUBTTL DELETE ROUTINE
BEGIN DELETE
;DELETA A LINE, A NUMBER OF LINES, OR A PAGE MARK
↑DELETE:SETZM LOLN ;JUST AS A START
TRNE FL,READOF ;NOT PERMITTED IN READ ONLY
NERROR ILC
PUSHJ P,GET2S ;GET TWO PAGE-LINE PAIRS
TRNN FL,PGSN ;ONLY ON IF A SECOND PAGE SPEC
DELT1: TRNN FL,TERMF ;CHECK FOR TERMINATOR
NERROR ILC
TRZN FL,LINSN ;LINE NUMBER SEEN?
JRST DELPG ;NO, MUST BE /A. DELETE PAGE MARK A
MOVE T1,HIPG ;GET THE PAGE NUMBER
MOVEM T1,DPG
MOVE SINDEX,LOLN ;AND LINE
PUSHJ P,FIND
DELT2: CAME T1,PGMK ;ARE WE AT A PAGE MARK?
PUSHJ P,ONMOV ;CHECK FOR RANGE
JRST DELEND
MOVEM T1,CLN ;MARK AS CURRENT LINE
TRO FL,LINSN ;AND ALSO THAT WE DID SOMETHING
PUSHJ P,DODEL ;GO DO A LINE DELETE
PUSHJ P,FINDN1 ;FIND NEXT BUT ACCEPT LINE IF ALREADY THERE
JRST DELT2 ;GO DO NEXT
DELEND: TRNN FL,LINSN ;DID WE SEE ANYTHING?
NERROR NLN ;NO, GIVE ERROR
MOVE T1,CPG ;YES, SET CURRENT PAGE
MOVEM T1,CPGL
JRST COMND ;AND GET NEXT COMMAND
DELPG: MOVE T1,HIPG ;GET THE DESIRED PAGE TO DELETE
MOVEM T1,DPG ;SET IT
SOJLE T1,DELER ;DO NOT TRY PAGE 1
MOVEI SINDEX,0 ;GUARANTEED TO FIND LINE IMMEDIATELY AFTER PAGE MARK
PUSHJ P,FIND ;GET IT
MOVE T2,CPG ;CHECK FOR MATCH
CAME T2,HIPG
DELER: NERROR NSP ;NO SUCH PAGE
PUSHJ P,FINDB ;GO BACK ONE
CAME T1,PGMK ;IS IT A PAGE MARK?
ERROR ICN ;CONFUSED, GIVE FATEL ERROR
MOVEI T1,2 ;COUNT IS 2
MOVEM T1,OCNT
SETZM NCNT ;AND NEW IS 0
PUSHJ P,INSED
SOS BGPG ;MAX PAGE IS NOW 1 LOWER
SOS INPG
PUSHJ P,FINDN1 ;GET THE NEXT LINE
JUMPE T1,COMND ;IF EOF THERE IS NO ORDER ERROR
CAMN T1,PGMK ;OR IF A PAGE MARK
JRST COMND
MOVEM T1,SVWD3 ;SAVE IT FOR COMPARE
PUSHJ P,FINDB ;FIND THE PREVIOUS ONE
JUMPE T1,COMND ;START OF FILE, ALL OK
CAME T1,PGMK ;ANOTHER PAGE MARK
CAMGE T1,SVWD3 ;CHECK THE ORDER
JRST COMND ;ALL OK
NERROR ORDER ;ALL WRONG
↑DODEL: SETZM NCNT ;NEW IS 0
PUSHJ P,GETLTH ;OLD LENGTH
MOVEM T1,OCNT
JRST INSED ;GO INSERT AND RETURN
BEND DELETE
SUBTTL REPLACE ROUTINE
BEGIN REPLAC
↑REPLAC:SETZM LOLN ;I REALLY SHOULD PUT THIS ELSEWHERE
TRNE FL,READOF ;NOT PERMITTED IN READ ONLY
NERROR ILC
PUSHJ P,GET2S ;WHAT DO WE WANT TO REPLACE?
CAIE C,"," ;HE CAN SPECIFY INCREMENT TOO
JRST CKTERM ;BUT HE DIDN'T, LOOK FOR TERMINATOR
PUSHJ P,SCAN ;GET INCR
TRNE FL,NUMF ;WHICH MUST BE A NUMBER
CAMN T1,[ASCID /00000/] ;NOT 0 FOR INCR
NERROR ILC
MOVEM T1,INCR
PUSHJ P,SCAN ;SCAN PAST
CKTERM: TRNN FL,PGSN ;WAS A SECOND PAGE GIVEN?
TRNN FL,TERMF ;OR PERHAPS NO TERMINATOR
NERROR ILC
MOVE T1,LOPG ;FIND START OF THE WORLD
MOVEM T1,DPG
MOVE SINDEX,LOLN
PUSHJ P,FIND ;WE WILL ALSO USE LOLN FOR START OF INSERT
SKIPN LOLN ;IN CASE HE SAID /A OR SOMETHING
MOVEM T1,LOLN ;USE START OF PAGE
MOVE T2,CPG ;GET CURRENT PAGE
CAME T2,LOPG ;AND FIND OUT IF ITS THE ONE WE WANT
NERROR NSP
NEXT: CAME T1,PGMK ;PAGE MARK STOPS THE WORLD
PUSHJ P,ONMOV ;CHECK RANGE
JRST GOINS ;OUT OF THINGS TO DELETE, INSERT
PUSHJ P,DODEL ;DELETE A LINE
SKIPE T1,(PNTR) ;ARE WE AT END OF BUFFER
JRST NEXT ;NO
NEXT1: MOVE T1,WC ;SEE IF ROOM TO INSERT
ADD T1,BUFP
CAML T1,FILPT
JRST NXTBF ;TOO FULL, GET NEXT BUFFER AND DELETE
SETZM OCNT ;INSERT A FRESH LINE
MOVE T1,LOLN ;THE LINE TO INSERT
MOVEM T1,LIBUF
PUSHJ P,OUTSN
PUSHJ P,RDLIN ;GET ONE
JRST FINDL ;LINE TOO LONG ERROR
MOVEM T1,NCNT ;SET UP NEW COUNT
PUSHJ P,INSED ;INSERT
PUSHJ P,FINDZ ;GET NEXT LINE, BUT NOT IN NEW BUFFER
MOVE T1,CPG ;SET UP .
MOVEM T1,CPGL
MOVE T1,LOLN
MOVEM T1,CLN
MOVE T2,INCR ;FIND NEXT LINE
PUSHJ P,ASCIAD
CAMG T1,INCR ;CHECK FOR WRAP AROUND
JRST FINDEL
MOVEM T1,LOLN ;AND SAVE IT
JRST NEXT1 ;CHECK TO SEE IF INSERT OR DELETE IN ORDER
GOINS: SKIPE T2,LOLN ;IS THERE REALLY ONE THERE?
CAMN T2,PGMK
JRST COMND ;TRIED TO REPLACE BLANK PAGE
MOVEM T2,HILN ;SET UP FOR INSERT
JRST ENTINS ;AND JUMP INTO THE MIDDLE OF IT
FINDL: MOVE T1,LOLN
MOVEM T1,CURINS
MOVE T1,CPG
MOVEM T1,IPG
FINDEL: PUSHJ P,FINDN1 ;GET THE NEXT LINE
CAME T1,PGMK ;QUIT IF PAGE MARK
PUSHJ P,ONMOV ;OR IF OUT OF RANGE
JRST LEVINS
PUSHJ P,DODEL ;DELETE IT
JRST FINDEL
NXTBF: PUSHJ P,FINDN1 ;GET TO A NEW BUFFER IF NECESSARY
JRST NEXT ;AND PROCEED TO NEXT
BEND REPLAC
SUBTTL JOIN ROUTINE
BEGIN JOIN ;CONNECT TWO LINES TOGETHER
↑JOIN: MOVEM C,SAVC ;BACK UP SCANNER ONE CHARACTER
PUSHJ P,GET1S ;GET LINE NUMBER
TRNN FL,TERMF
NERROR ILC
MOVE T1,HIPG
MOVEM T1,DPG
MOVE SINDEX,HILN ;FIND THE CORRECT LINE
PUSHJ P,FIND
MOVE T2,CPG
MOVE T1,(PNTR)
CAMN T2,HIPG
CAME T1,HILN
NERROR NLN
MOVEM T2,CPGL
MOVEM T1,CLN
SETZM LIBUF ;TO ELIMINATE GARBAGE AT END OF LINE
MOVE T1,[XWD LIBUF,LIBUF+1]
BLT T1,LIBUF+MXWPL+1
MOVE T2,PNTR ;GET THE POINTER TO THE LINE
MOVE T3,(T2) ;PICK UP THE FIRST WORD
MOVEI T4,LIBUF ;THE PLACE TO PUT IT
JRST SALT3 ;TRANSFER
SALT2: SKIPE T3,(T2)
TRNE T3,1 ;IS IT THE END OF THE LINE
JRST SALT1
SALT3: MOVEM T3,(T4) ;PUT IT AWAY
ADDI T4,1
AOJA T2,SALT2
SALT1: MOVEI T1,-LIBUF(T4)
MOVEM T1,OCNT
IMULI T1,5 ;GET COUNT OF CHRS
SUBI T1,6 ;WE WILL HAVE TO FIND THE TRUE END
SUBI T4,2
HRLI T4,(<POINT 7,0,27>) ;SET UP POINTER
FEND1: ILDB T2,T4
CAIE T2,15
AOJA T1,FEND1
PUSH P,T1
PUSHJ P,FINDN ;GET THE LINE TO JOIN IT TO
CAME T1,PGMK
SKIPN T1
NERROR NNN ;NO LINE THERE TO CONNECT TO
POP P,T2 ;COUNT
MOVEI T1,1(PNTR)
HRLI T1,(<POINT 7,0,6>) ;SET TO POINT THERE
ADD T4,[XWD 70000,0]
TRN1: ILDB T3,T1
IDPB T3,T4
ADDI T2,1
CAIL T2,MXWPL*5+6
NERROR LTL
CAIE T3,12
JRST TRN1
SUBI T1,-1(PNTR)
PUSH P,OCNT
HRRZM T1,OCNT ;SIZE OF OLD SECOND LINE
SETZM NCNT
PUSHJ P,INSED
PUSHJ P,FINDB ;BACK UP
POP P,OCNT ;GET ITS SIZE
SUBI T4,LIBUF-1
HRRZM T4,NCNT
PUSHJ P,INSED
JRST COMND
BEND JOIN
SUBTTL ALTER ROUTINES
BEGIN ALTER
IFN STANSW,<
↑QPAND: SKIPA T1,[PUSHJ P,QLIN] ;EXPAND LINE USING SYSTEM EDITOR
↑ZALT: MOVE T1,[PUSHJ P,ZLIN] ;ALTER LINE USING SYSTEM EDITOR
TRNN FL,DPYF ;ILLEGAL IF NOT A DPY
>
IFE STANSW,<
↑ZALT: ↑QPAND:
>
NERROR ILC ;FOR WHATEVER REASON
IFN STANSW,<
JRST ALT111 ;CONTINUE
>
↑XPAND: SKIPA T1,[PUSHJ P,XTEND] ;EXPAND LINE USING INTERNAL EDITOR
↑ALTER: MOVE T1,[PUSHJ P,ALTLIN] ;ALTER LINE USING INTERNAL EDITOR
ALT111: MOVEM T1,ZSW ;FOR LATER EXECUTION
SETZM LOLN ;FOR START OF PAGE
TRNE FL,READOF ;NOT PERMITTED IN READ ONLY
NERROR ILC
PUSHJ P,GET2S ;GET THE RANGE
TRNN FL,TERMF ;CHECK FOR PROPER END
NERROR ILC ;UNEND
MOVE T1,LOPG ;START TO PROCESS
MOVEM T1,DPG
MOVE SINDEX,LOLN
PUSHJ P,FIND ;GO GET IT
TRZ FL,LINSN ;NOT SEEN YET
ALT1: PUSHJ P,ONMOV ;CHECK FOR IN RANGE
JRST ALT2 ;NO, FINISH UP
TRO FL,LINSN ;WE DID SEE SOMETHING
CAMN T1,PGMK ;CHEC FOR A PAGE
JRST ALT3 ;DO NNT TRY TO CHANGE THIS
MOVEM T1,CLN ;NOW, IN CASE WE SAID ALTMODE
MOVE T1,CPG ;SAME FOR PAGE
MOVEM T1,CPGL
XCT ZSW ;CALL ALTLIN OR ZLIN
JRST LEVINS ;HE SAID ALTMODE
PUSHJ P,INSED ;GO INSERT
ALT4: PUSHJ P,FINDN ;GET THE NEXT LINE
PUSHJ P,FILLB ;AND CHECK FOR BUFFER OVERFLOW
MOVE T1,(PNTR) ;GET LINE FOR ONMOV
JRST ALT1 ;CONTINUE LOOP
ALT3: AOS T2,CPG ;WE ARE ON A LATER PAGE NOW
MOVEM T2,CPGL ;SAVE AS .
PUSHJ P,PGPRN ;PRINT HIM A MESSAGE
MOVE T1,[ASCID /00000/] ;SET TO FIRST? LINE
MOVEM T1,CLN ;FOR .
JRST ALT4 ;CONTINUE PAST IT
ALT2: TRNN FL,LINSN ;WAS THERE ANYTHING THERE?
NERROR NLN ;NO, GIVE ERROR
MOVE T1,CPG ;GET CURRENT PAGEE
MOVEM T1,CPGL ;SAVE AS .
JRST COMND ;GO
BEND ALTER
BEGIN ALTLIN
↑XTEND: PUSHJ P,SETALT ;SET UP LINE FOR ALTERATION
MOVSI T2,1 ;VERY LARGE NUMBER
PUSHJ P,ALTSP ;SPACE OUT TO END
MOVEI T2,0 ;ZERO INCREMENT TO START
PUSHJ P,ALTIN ;INSERT REST OF LINE
JRST ALTN1 ;CONTINUE ALTERATION
↑ALTLIN:PUSHJ P,SETALT ;SET UP LINE FOR ALTERATION
↑ALTN1: IFE FULDPX,<MOVE T1,[POINT 7,DDTINB] ;SET UP FOR DDT FETCH
MOVEM T1,DDTINP ;INTO POINTER
SETZM DDTINB ; TO INSURE A FETCH THE FIRST TIME>
ALTLP2: MOVEI T2,0 ;ZERO REPEAT COUNT
ALTLP: TRZ FL2,ALTDUP ;TURN DUPLEXING BACK OFF
PUSHJ P,GNCH1 ;GET ON CHR IN DDT SUBMODE
TLNE CS,LETF⊗16 ;CHECK FOR LETTER
TRZ C,40 ;AND CONVERT TO UPPER CASE
MOVSI T1,-ALTLG ;GET LENGTH OF COMMAND TABLE
CAME C,ALTAB1(T1) ;CHECK FOR EQUAL
AOBJN T1,.-1 ;NO, TRY AGAIN
JUMPGE T1,ALTLP2 ;AOBJN RAN OUT, IGNORE
PUSHJ P,@ALTAB2(T1) ;EXECUTE COMMAND
JRST ALTLP2 ;RESET REPEAT COUNT AND GET NEW COMMAND
JRST ALTLP ;SKIP RETURN FROM DIGITS NO COUNT RESET
ALTAB1: " "↔"I"↔"D"↔"S"↔"K"↔"Q"↔12↔"C"↔177↔"U"-100
"R"↔"L"↔"P"↔"J"↔"0"↔"1"↔"2"↔"3"↔"4"↔"5"↔"6"↔"7"↔"8"↔"9"↔"0"
ALTLG←.-ALTAB1
ALTAB2: ALTSP↔ALTIN↔ALTDL↔ALTSR↔ALTKL↔ALTALT↔ALTFN↔ALTCN
ALTBS↔ALTCU↔ALTRP↔ALTLN↔PRINT↔JOIN
REPEAT =10,<ALTDG>
IFN STANSW,<
↑QLIN: PUSHJ P,SETALT ;GET READY FOR LINE
TROA FL2,ALTDUP ;WILL SPACE TO END AFTER LINE LOADED
↑ZLIN:
PUSHJ P,SETALT ;SET UP FOR LINE ALTERATION
↑ZLNN1: TTYUUO 11, ;CLEAR OUT SYSTEM INPUT BUFFER
OPDEF PTYUUO [711B8] ;FOR COMMUNICATING WITH SYSTEM
MOVNI T1,1
TTCALL 6,T1 ;GET CHARACTERISTICS
HLRS T1 ;COPY BITS TO RIGHT HALF(SAVE)
TLO T1,20 ;PRESERVE LOWER CASE
TTCALL 7,T1 ;IF THERE
HRLZS T1 ;RIGHT GOES TO LEFT
PTYUUO 15,[0
POINT 7,LIBUF+1,6] ;LINE →SYSTEM (WITHOUT TAB)
TRZE FL2,ALTDUP ;SHOULD WE GO TO END?
PTYUUO 7,[0
211] ;YES, SEND [CTRL1] TAB
TRZE FL2,ZSPA ;WANT TO SPACE OUT?
JRST [CTSP: PTYUUO 7,[0
240] ;YES, PUT OUT CTRL SPACES
SOJGE T2,CTSP ;UNTIL DONE
JRST .+1]+1
TTCALL 7,T1 ;PUT OLD MODE BACK
SETZM LIBUF+1 ;NOW CLEAR WHAT HAS BECOME AN
MOVE T1,[XWD LIBUF+1,LIBUF+2] ;INPUT BUFFER
BLT T1,LIBUF+MXWPL+1
MOVE ALTP,[POINT 7,LIBUF+1,6];FOR DEPOSITING
; MOVE ALTP,[POINT 7,LIBUF+1];FOR DEPOSITING
; MOVEI T1,177 ;NON-PRINTER REPLACES TAB TEMPOR.
; IDPB T1,ALTP
TTCALL 14,T3 ;WAIT FOR ACTIVATION, GET LINE COUNT
MOVE T2,T3 ;SAVE TOTAL COUNT
SETZM SVCRLC ;ASSUME NO INSERTION OF CR
SETSTS TTY,401 ;TURN ON DUPLEXING AGAIN
ZLUP: TTCALL T1 ;NEXT CHAR BACK FROM THE WARS
CAIN T1,412 ;INSERTING A CR?
JRST [MOVEM ALTP,SVCRLC ;SAVE BP WHERE CR OCCURRED
IBP SVCRLC ;ACTUALLY THE NEXT
SUB T2,T3 ;COMPUTE #CHARS MOVED
MOVEM T2,ALTCNT ;THIS IS WHERE `A' CODE EXPECTS
JRST .+1] ;CONTINUE
TRZ T1,600 ;TURN OFF CONTROL BITS, IF ANY
CAIE T1,12 ;IGNORE CR-LF PAIRS
CAIN T1,15
JRST LUPTRM ;LIKE THIS
IDPB T1,ALTP
CAIN T1,175 ;ALTMODE?
JRST [TTCALL 11, ;YES, GET OUT
POPJ P,]
LUPTRM: SOJG T3,ZLUP ;GET ALL THE CHARACTERS
ZDUN: MOVEI T1,15
IDPB T1,ALTP
MOVEI T1,12 ;PUT CR-LF IN BY HAND
IDPB T1,ALTP
SKIPE SVCRLC ;WAS THERE A CTRL2 CR?
JRST ZINSCR ; YES, INSERT CRLF
; TTYUUO 3,LIBUF+1 ;NOW TYPE THE (NEW) LINE
MOVEI T1,[ SIXBIT/TTY/
POINT 0,LIBUF+1,6] ;NEW TTYMES METHOD
CALLI T1,400047 ;NEW FORM OF TTYMES, POSITION FIELD
JFCL ; IF YOU LOSE, YOU LOSE
MOVEI T1,11 ;PUT IN IMPLIED TAB
DPB T1,[POINT 7,LIBUF+1,6]
; ABOVE WAS DONE SO THAT INSERTING A CARRIAGE RETURN IN
; `Z' MODE WOULDN'T LOOK FUNNY (WE DO THE DUPLEXING, SO
; WE HAVE CONTROL -- RECOGNIZE THAT?)
SUBI ALTP,LIBUF-1 ;LINE LENGTH FOR INSED
HRRZM ALTP,NCNT
AOS (P) ;SKIP RETURN
POPJ P,
ZINSCR: SETOM ZCOMMND ;TELL COMMON CODE WHO CALLED
SETZM ALTINC ;USE STANDARD INCR
MOVE ALTP,SVCRLC ;BP WHEN CR WAS INSERTED
JRST INSCR1 ;USE COMMON CODE TO INSERT
>
BEGIN SETALT
↑SETALT: SETZM LIBUF ;ZERO OUT INTERNAL LINE BUFFER
MOVE T1,[XWD LIBUF,LIBUF+1]
BLT T1,LIBUF+MXWPL+1
MOVEI T1,LIBUF ;SET POINTER TO TRANSFER
MOVE T2,PNTR
MOVE T3,(T2) ;GET THE FIRST WORD (SEQ NUM)
JRST SALT3
SALT2: SKIPE T3,(T2) ;PICK UP A WORD AND CHECK FOR 0
TRNE T3,1 ;CHECK FOR SEQ NTM
JRST SALT1 ;END OF THIS LINE
SALT3: MOVEM T3,(T1) ;SAVE IT AWAY
ADDI T1,1 ;INCREMENT POINTERS
AOJA T2,SALT2
SALT1: MOVE ALTP,[POINT 7,LIBUF+1,13] ;SET UP POINTER
SETZM ALTCNT ;SO FAR WE ARE 0 CHRS INTO LINE
SUBI T1,LIBUF ;GET COUNT OF OLD LINE
HRRZM T1,OCNT ;AND SAVE IT FOR INSED
IFN FULDPX,<IFN STANSW,<SETSTS TTY,601>
IFE STANSW,<SETSTS TTY,201 ;TURN OFF DUPLEXING>
TRZ FL2,RUBF!ALTDUP!RUBF2 ;TURN OFF IN RUBOUT FALG AND NO DUPLEXING>
IFE FULDPX,< CALLI 400001
TRZ FL2,ALTDUP>
SETZM ALTFLG ;NOTHING INSERTED SO FAR
MOVE T1,LIBUF ;PRINT LINE NUMBER AND TAB
JRST OUTSN
BEND SETALT
↑SETALT←SETALT
IFN FULDPX,<
DEFINE OFFRUB
< TRZE FL2,RUBF2
TTYUUO 3,[ASCII /\\/]
TRZE FL2,RUBF
TTYUUO 1,["\"]>>
IFE FULDPX,<
DEFINE OFFRUB <>>
IFN FULDPX,<
DEFINE ONRUB
< TRZE FL2,RUBF2
TTYUUO 3,[ASCII /\\/]
TRON FL2,RUBF
TTYUUO 1,["\"]>>
IFE FULDPX,<DEFINE ONRUB<>>
BEGIN GNCH1
IFE FULDPX,<GNCH1A: ILDB C,DDTINP ;GET A CHR IN DDT MODE (1 FROM BUFFER)
JUMPN C,GNCH1C ;IF NOT 0 IT IS OK
MOVE C,[POINT 7,DDTINB] ;0 MUST BE OUT, GET MORE
MOVEM C,DDTINP
CALLI C,1 ;DDTIN WILL USE RH=DDTINB FOR INPUT
JRST GNCH1A ;NOW GO GET A CHARACTER>
IFN FULDPX,<GNCH1A: TTYUUO 0,C
ANDI C,177>
GNCH1C: CAIE C,175 ;NEVER DUPLEX ALTMODE
TRNN FL2,ALTDUP ;AND NOT UNLESS DESIRED
POPJ P,
CAIE C,12 ;NOT LINE FEED
CAIN C,15 ;OR RETURN
POPJ P,
CAIN C,177 ;AND FINALLY IGNORE RUBOUT
POPJ P,
OFFRUB ;IF WE ARE DUPLEXING WE ARE NOT DELETING
IFN FULDPX,<TTYUUO 1,C ;TYPE>
IFE FULDPX,<SETZM SQBUF ;AS GOOD A PLACE AS ANY
DPB C,[POINT 7,SQBUF,6]
PUSH P,C
MOVEI C,SQBUF
CALLI C,3
POP P,C>
POPJ P,
↑GNCH1: PUSHJ P,GNCH1A ;GET A CHR IN DDT MODE
CAIN C,175 ;CONVERT ALTMODE TO 200
MOVEI C,200
TLNN FL,QMODF
CAIE C,"?" ;CHECK FOR QUESTION MARK
JRST GNCH1B ;NO, THIS CHR IS OK
PUSHJ P,GNCH1A ;GET ANOTHER
SKIPE CTBL(C) ;IF 0 HN CTBL, KEEP IT
MOVS C,CTBL(C) ;GET ALTERNATE CODE
ANDI C,177 ;GET RID OF EXTRA BITS
GNCH1B: MOVE CS,CTBL(C) ;LOAD CS
TLNE CS,LETF⊗16 ;CHECK FOR LETTER
TDC C,CASEBT ;AND APPLY CASE CONVERRION
POPJ P, ;ALL DONE
BEND GNCH1
ALTDG: IMULI T2,=10 ;ACCUMULATE REPEAT COUNT
ADDI T2,-"0"(C)
AOS (P) ;SKIP RETURN SO AS NOT TO 0 RPT. CNT.
POPJ P,
↑ALTSP: OFFRUB
BEGIN ALTSP
ALTSP2: LDB C,ALTP ;GET THE CHR WE ARE POINTING AT
CAIN C,15 ;IF RETURN THEN AS FAR AS CAN GO
JRST ALTSP1 ;SO QUIT
PUSHJ P,OCHR ;PRINT IT
IBP ALTP ;ADVANCE POINTER
AOS ALTCNT ;AND COUNT
SOJG T2,ALTSP2 ;DO CORRECT NUMBER OF TIMES
ALTSP1: OUTPUT TTY,0 ;FORCE IT OUT
POPJ P,
BEND ALTSP
BEGIN ALTIN
↑ALTIN: TRO FL2,ALTDUP ;TURN ON DUPLEXING
MOVEM T2,ALTINC ;SAVE IN CASE HE INSERTS A RETURN
ALTIN1: PUSHJ P,GNCH1 ;GET A CHARACTER
CAIN C,15 ;IGNORE RETURN
JRST ALTIN1
CAIN C,12 ;FINISH ON LINE FEED OR ALTMODE
JRST INSCR ;GO INSERT A CRLF
CAIN C,200
POPJ P, ;GO AWAY
CAIN C,177 ;CHECK FOR BACKSPACE
JRST ALTIBS ;AND DELETE CHR TO LEFT
MOVE T3,ALTP ;GET SET TO SHIFT THINGS
PUSH P,ALTCNT ;SAVE THIS FOR LATER
LDB T1,T3 ;GET CHR FROM LINE
ALTIN2: DPB C,T3 ;SHIFT LINE
JUMPE C,ALTIN3 ;DONE
AOS ALTCNT ;COUNT IT
ILDB C,T3
DPB T1,T3
JUMPE T1,ALTIN3 ;DONE
AOS ALTCNT ;COUNT
ILDB T1,T3
JRST ALTIN2
ALTIN3: MOVE T2,ALTCNT ;SEE IF OVERFLOW HAPPENED
CAIL T2,MXWPL*5
NERROR LTL ;YES
POP P,ALTCNT ;RESTORE OLD COUNT
IBP ALTP ;ADVANCE POINTER
AOS ALTCNT ;AND COUNT
JRST ALTIN1 ;GO GET MORE
INSCR: OFFRUB
SETZM ZCOMMND ;NOT CALLED FROM `Z' COMMAND
TERPRI (T1)
↑INSCR1:
SKIPN T1,ALTINC ;DID HE SPECIFY AN INCREMENT?
SKIPA T3,INCR ;NO, USE STANDARD
PUSHJ P,ASCON ;CONVERT TO ASCII
MOVE T1,T3 ;FIND THE NEW LINE NUMBER
MOVE T2,LIBUF ;CURRENT ONE
PUSHJ P,ASCIAD ;ADD
PUSH P,T1 ;SAVE RESULT
PUSHJ P,FINDN ;GET THE NEXT ONE
POP P,T2
CAMG T2,LIBUF ;IS THERE A WAR PROBLEM
JRST INCBAD ;YES, WE MUST TRY TO COMPUTE ONE
JUMPE T1,INCOK ;END OF FILE, ANY INC IS OK
CAME T1,PGMK ;ALSO OK IF A PAGE MARK
CAMGE T2,T1 ;OR IN CORRECT ORDER
JRST INCOK
INCBAD: CAME T1,PGMK
SKIPN T1
MOVE T1,[ASCID /9999:/] ;ONE OVER THE TOP OF THE WORLD
MOVEM T2,LIBUF2 ;SAVE IN CASE NOTHING WILL WORK
MOVE T2,LIBUF ;GET CURRENT
PUSHJ P,ASCAV ;FIND AVERAGE
CAME T2,LIBUF ;THERE MAY HAVE ONLY BEEN A DIF OF 1
JRST INCOK ;ALL IS WELL
RERROR ORDER ;TELL HIM
PUSHJ P,FINDB ;GET BACK WHERE WE BELONG
SKIPE ZCOMMND ;WERE WE IN Z MODE?
JRST ZERCOR ; YES
PUSHJ P,ERCOR ;TYPE OUT LINE TO CURRENT POINT
JRST ALTIN1 ;AND CONTINUE INSERT
ZERCOR: TERPRI (T1) ;NOW PRINT CRLF
TRO FL2,ZSPA ;SPACE OUT N
PUSH P,ALTCNT ;WILL BE ZEROED BY SETALT
PUSHJ P,SETALT ;SET UP FOR ALTER AGAIN
POP P,T2 ;THIS IS N
SOJA T2,ZLNN1 ;GO BACK AND TRY AGAIN
INCOK: MOVEM T2,LIBUF2 ;SAVE IT
MOVEM T2,CLN ;AND SET AS CURRENT LINE
PUSHJ P,FINDB ;BACK UP TO WHERE WE BELONG
MOVE T1,[XWD LIBUF+1,LIBUF2+1]
BLT T1,LIBUF2+MXWPL+1 ;SAVE OLD BUFFER
PUSH P,ALTP ;SAVE POINTER
MOVEI C,15
DPB C,ALTP ;AND TERMINATE THIS LINE
MOVEI C,12
IDPB C,ALTP
MOVEI C,0 ;FILL OUT LINE WITH NULLS
INSC2: TLNN ALTP,760000
JRST INSC3
IDPB C,ALTP
JRST INSC2
INSC3: SKIPN ZCOMMND ;IN Z MODE?
JRST INSC33 ; NO
; TYPE OUT LINE, REPLACE 177 WITH TAB
SETZM 1(ALTP) ;MAKE SURE THERE'S A NULL
MOVEI T1,[ SIXBIT/TTY/
POINT 0,LIBUF+1,6];NEW TTYMES USES POSITION FIELD
CALLI T1,400047 ;TTYMES, FROM 2D CHAR
JFCL ;IGNORE LOSSAGE (SHOULDN'T HAPPEN)
; TTYUUO 3,LIBUF+1 ;TYPE WHAT IS THERE
MOVEI C,11 ;PUT TAB IN
DPB C,[POINT 7,LIBUF+1,6]
INSC33: SUBI ALTP,LIBUF-1 ;FIND COUNT
HRRZM ALTP,NCNT
PUSHJ P,INSED ;REPLACE OLD LINE
PUSHJ P,FINDN ;MOVE UP TO NEXT
PUSHJ P,FILLB ;AND DUMP IF OVERFLOW
SETZM OCNT ;THIS IS A NEW LINE GOING IN
MOVE T1,LIBUF2 ;MOVE LINE NUMBER OVER
MOVEM T1,LIBUF
SETZM LIBUF+1
MOVE T1,[XWD LIBUF+1,LIBUF+2]
BLT T1,LIBUF+MXWPL+1 ;ZERO OUT REST
POP P,T2 ;RESTORE POINTER TO REST OF LINE
MOVE ALTP,[POINT 7,LIBUF+1] ;DEST POINTER
ADD T2,[XWD 70000,LIBUF2-LIBUF] ;ADJUST INPUT POINTER
MOVEI C,11 ;AND SET UP THE TAB
MOVNEW: IDPB C,ALTP
CAIN C,12
JRST DONNEW ;FINISHED MOVING REST OF LINE
ILDB C,T2 ;PICK UP ONE
JRST MOVNEW
DONNEW: MOVEI ALTP,1-LIBUF(ALTP) ;GET COUNT
MOVEM ALTP,NCNT
PUSH P,ALTP ;AND SAVE
PUSHJ P,INSED ;INSERT
MOVE ALTP,[POINT 7,LIBUF+1,13] ;SET UP FOR ALTER
SETZM ALTCNT
POP P,OCNT ;SET FOR OLD COUNT
SKIPE ZCOMMND ;FROM Z COMMAND?
JRST ZLIN ; YES, GO ALTER THIS LINE
MOVE T1,LIBUF
PUSHJ P,OUTSN
SETOM ALTFLG ;WE HAVE INSERTED AND ALTALT SHOULD CALL FILLB
JRST ALTIN1 ;AND CONTINUE INSERTING
POPJ P,
ALTIBS: MOVEI T2,0 ;SET COUNT TO 0
MOVEM ALTP,SVALTP ;SAVE POINTER
PUSHJ P,ALTBS ;DO A BACKSPACE
EXCH ALTP,SVALTP ;GET BACK AND SAVE CURRENT
PUSHJ P,ALTDL3 ;DELETE THAT CHR
JRST ALTIN1 ;GET MORE
BEND ALTIN
↑ALTIN←ALTIN
BEGIN ALTDL
↑ALTDL: MOVEM ALTP,SVALTP ;SAVE CURRENT POINTER POSITHON
ALTDL1: LDB C,ALTP ;GET CURRENT CHR
CAIN C,15 ;AT END OF LINE?
JRST ALTDL5 ;YES, GO FINISH OFF
CAIG T2,3 ;FEWER THAN 3 MORE TO DELETE
IFE FULDPX,<JRST [PUSHJ P,OCHR ;PRINT IT
MOVEI C,"\" ;AND A \
PUSHJ P,OCHR
JRST .+1]>
IFN FULDPX,<JRST [PUSH P,C
MOVEI C,"\"
TRNN FL2,RUBF2
PUSHJ P,OCHR
TRZE FL2,RUBF
PUSHJ P,OCHR
TRON FL2,RUBF2
PUSHJ P,OCHR
POP P,C
PUSHJ P,OCHR
JRST .+1]>
IBP ALTP ;ADVANCE POINTER
SOJG T2,ALTDL1 ;CHECK COUNT AND CONTINUE
ALTDL5: OUTPUT TTY,0 ;FORCE OUTPUT
↑ALTDL3:MOVE T3,SVALTP ;GET BACK POINTER
ALTDL4: LDB C,ALTP ;MOVE LINE DOWN
DPB C,T3
JUMPE C,ALTDL2 ;DONE?
IBP ALTP ;ADVANCE POINTERS
IBP T3
JRST ALTDL4
ALTDL2: MOVE ALTP,SVALTP ;RESTORE POINTER AGAIN
POPJ P, ;AND LEAVE
BEND ALTDL
PRINT: PUSH P,ALTCNT ;SAVE CURRENT COUNT
PUSHJ P,ALTLN ;PRINT REST OF LINE AND START OVER
POP P,T2 ;GET BACK COUNT
CAILE T2,0 ;AND SPACE IF NOT 0
JRST ALTSP
POPJ P,
BEGIN ALTSRC
↑ALTSR: OFFRUB
PUSHJ P,GNCH1 ;GET THE CHARACTER TO SEARCH FOR
ALTSR1: PUSH P,T2 ;SAVE NUMBER OF TIMES TO SEARCH
PUSHJ P,ALTCS ;CALL COMMON SEARCH ROUTINE
PUSH P,C ;SAVE THE CHARACTER
PUSHJ P,ALTSP ;GO SPACE CORRECT NUMBER
POP P,C ;RESTORE CHR
POP P,T2 ;AND COUNT
SOJG T2,ALTSR1 ;CONTINUE
POPJ P,
ALTCS: MOVEI T2,1 ;CREATE A REPEAT COUNT
LDB T3,ALTP ;CHECK TO SEE IF AT END OF LINE
CAIN T3,15
POPJ P,
MOVE T1,ALTP ;GET A COPY OF THE POINTER
ALTCS1: ILDB T3,T1 ;GET A CHARACTER
CAIE T3,15 ;DONE IF END OF LINE
CAMN T3,C ;OR A MATCH
POPJ P,
AOJA T2,ALTCS1 ;ELSE KEEP COUNT AND KEEP LOOKING
↑ALTKL: PUSHJ P,GNCH1 ;ALMOST LINE ALTSR
ALTKL1: PUSH P,T2
PUSHJ P,ALTCS
CAIN T3,15 ;BUT GIVE UP IF CHR NOT FOUND
JRST TPOPJ
PUSH P,C
PUSHJ P,ALTDL ;DELETE THAT NUMBER
POP P,C
POP P,T2
SOJG T2,ALTKL1
POPJ P,
↑TPOPJ: POP P,T2 ;NEED TO CLEAR STACK
POPJ P,
BEND ALTSRC
; "Q" -- IGNORE THIS LINE
; (RATHER, IGNORE ANY CHANGES TO IT)
ALTALT: OFFRUB
SKIPN ALTFLG ;SHOULD WE DO A FILLB?
JRST ALTAL1
PUSHJ P,FINDN
PUSHJ P,FILLB ;YES, WE HAVE INSERTED SOMETHING
IFN FULDPX,<ALTAL1:IFN STANSW,<SETSTS TTY,401>
IFE STANSW,<SETSTS TTY,1 ;DUMPLEXING BACK ON>>
IFE FULDPX,<ALTAL1: CALLI 400001>
JRST TPOPJ ;AND RETURN
BEGIN ALTFN
↑ALTFN: OFFRUB
MOVEI T2,1000 ;FINISH UP LINE
PUSHJ P,ALTSP ;BY PRINTING A LARGE NUMBER OF SPCAES
TERPRI (T1)
IFN FULDPX,<IFN STANSW,<SETSTS TTY,401>
IFE STANSW,<SETSTS TTY,1 ;GET OUT OF NON-DUPLEX MODE>>
IFE FULDPX,< CALLI 400001>
ALTFN1: ILDB C,ALTP ;LOOK ONE CHR OVER
CAIE C,12 ;THIS SHOULD BE THE LINE FEED
NERROR ILFMT ;SOMETHING IS WRONG
MOVEI C,0 ;ZERO REMAINDER OF LINE
ALTFN2: TLNN ALTP,760000 ;ALL DONE?
JRST ALTFN3 ;YES
IDPB C,ALTP ;NO, PUT IN ANOTHER 0
JRST ALTFN2
ALTFN3: SUBI ALTP,LIBUF-1 ;GET SIZE OF NEW LINE
HRRZM ALTP,NCNT ;AND SAVE FOR INSED
AOS -1(P) ;SET FOR SKIP RETURN
POP P,T1 ;GET RID OF THE EXTRA CALL
POPJ P, ;RETURN TO CALLER OF ALTLIN
BEND ALTFN
ALTCU: OFFRUB
IFEDUPL {CALLI 400001}
MSSG (T1,<↑U
>)
JRST SETALT ;GO RESTART LINE AND FORGET EDIT SO FAR
ALTRP: PUSHJ P,ALTDL ;REPLACE IS DELETE THEN INSERT
MOVEI T2,0
JRST ALTIN
BEGIN ALTCN
↑ALTCN: OFFRUB
TRO FL2,ALTDUP ;TURN ON DUPLEXING
ALTCN2: LDB C,ALTP ;AT END OF LINE?
CAIN C,15
POPJ P, ;YES, STOP
ALTCN1: PUSHJ P,GNCH1 ;GET A CHARACTER
CAIE C,177 ;DO NOT LET HIM INSERT A RUBOUT
CAIN C,12 ;IGNORE CRET
JRST ALTCN1
CAIE C,200 ;STOP ON ALTMODE AND LINE FEED
CAIN C,15
POPJ P,
DPB C,ALTP ;REPLACE IT
IBP ALTP ;ADVANCE POINTER
AOS ALTCNT ;AND COUNT
SOJG T2,ALTCN2 ;CONTINUE
POPJ P,
BEND ALTCN
BEGIN JOINA
↑JOIN: OFFRUB
PUSHJ P,FINDN ;GO SEE IF NEXT LINE IS REALLY THERE
CAME T1,PGMK
SKIPN T1
JRST ILCER ;MAKE IT ILLEGAL IF NO LINE THERE
MOVEM T1,LIBUF2 ;SAVE ITS NUMBER
SETZM LIBUF2+1
MOVE T1,[XWD LIBUF2+1,LIBUF2+2]
BLT T1,LIBUF2+MXWPL+1 ;CLEAR OUT REST OF BUFFER
PUSH P,ALTP ;SAVE POINTER TO THIS LINE
ADD ALTP,[XWD 70000,0] ;BACK IT UP
MOVE T2,[POINT 7,LIBUF2+1]
MOVEI C,11
MOVEI T1,6 ;COUNT THE CHARACTERS
MOVLIN: IDPB C,T2
ILDB C,ALTP
CAIE C,15 ;END OF LINE?
AOJA T1,MOVLIN ;KEEP COUNT
MOVEI ALTP,1(PNTR) ;GET POINTER TO SECOND LINE
HRLI ALTP,(<POINT 7,0,6>)
TRN1: ILDB C,ALTP
IDPB C,T2
ADDI T1,1
CAIL T1,MXWPL*5+6 ;CHECK SIZE
JRST LTLER
CAIE C,12
JRST TRN1 ;NOT DONE YET
EXCH T2,(P) ;SAVE OUTPUT POINTER AND GET OLD ALTP BACK
SUBI ALTP,-1(PNTR) ;GET OLD COUNT OF SECOND LINE
PUSH P,ALTP ;AND SAVE IT
MOVEI C,15 ;FINISH CURRENT LINE
DPB C,T2
MOVEI C,12
IDPB C,T2
MOVEI C,0
INSC2: TLNN T2,760000
JRST INSC3 ;FILL WITH NULLS
IDPB C,T2
JRST INSC2
INSC3: SUBI T2,LIBUF-1 ;GET COUNT
HRRZM T2,NCNT
PUSHJ P,FINDB ;BACK UP TO POINT TO IT
PUSHJ P,INSED
PUSHJ P,FINDN
PUSHJ P,FILLB
POP P,OCNT ;OLD CONT
HRRZS OCNT
POP P,ALTP ;GET OUTPUT POINTER BACK
SUBI ALTP,LIBUF2-1
HRRZM ALTP,NCNT
MOVE T1,[XWD LIBUF2,LIBUF]
BLT T1,LIBUF+MXWPL+1
PUSHJ P,INSED
SETOM ALTFLG ;MARK AS NEED TO DO FILLB
MOVE T1,NCNT ;GET THE COUNT JUST USED
MOVEM T1,OCNT ;AND SET AS THE OLD COUNT
MOVE ALTP,[POINT 7,LIBUF+1,13] ;SET UP
SETZM ALTCNT
TERPRI (T1)
MOVE T1,LIBUF
MOVEM T1,CLN ;SET UP CURRENT LINE
JRST OUTSN ;AND PRINT NUMBER
LTLER: RERROR LTL
POP P,ALTP ;RESTORE ALTP
SKIPA
ILCER: RERROR NNN
PUSHJ P,FINDB ;MOVE BACK TO RIGHT PLACE
↑ERCOR: PUSH P,ALTCNT ;SAVE COUNT
SETZM ALTCNT
MOVE ALTP,[POINT 7,LIBUF+1,13] ;SET BACK TO START
PUSHJ P,ALTCBS ;PRINT LINE NUMBER
POP P,T2 ;COUNT
JUMPN T2,ALTSP ;AND SPACE OVER
POPJ P, ;NO SPACES TO DO
BEND JOINA
BEGIN ALTBS
↑ALTBS: CAMN ALTP,[POINT 7,LIBUF+1,13] ;ARE WE AT START OF LINE
JRST ALTCBS ;YES, GIVE CR/LF AND SEQ NUMBER
IFE FULDPX,<MOVEI T1,[ASCIZ /\/]
CALLI T1,3 ;PRINT A \>
ONRUB
SUBI ALTP,1 ;BACKSPACE POINTER
REPEAT 3,<IBP ALTP>
ILDB C,ALTP
IFN FULDPX,<PUSHJ P,OCHR>
SOS ALTCNT ;DECREASE COUNT
SOJG T2,ALTBS ;MORE,MORE
IFN FULDPX,<OUTPUT TTY,0>
POPJ P,
↑ALTCBS:OFFRUB
TERPRI (T1)
MOVE T1,LIBUF ;ALSO PRINT SEQ NUM
JRST OUTSN
BEND ALTBS
ALTLN: MOVEI T2,1000 ;FINISH PRINTING THE LINE
PUSHJ P,ALTSP
MOVE ALTP,[POINT 7,LIBUF+1,13] ;POINTER TO START
SETZM ALTCNT ;RESET COUNT
JRST ALTCBS ;AND PRETEND A BACKSPACE
BEND ALTLIN
SUBTTL RENUMBER COMMAND
BEGIN NUMBER
;RENUMBER SELECTED LINES
↑NUMBER:MOVE T1,[ASCID /00100/] ;IF NO INCR IS SEEN
MOVEM T1,REINC ;WE WILL USE 100
MOVEM T1,INCST
SETZM LOLN ;GET THIS SET TO START THINGS OFF
PUSHJ P,SCAN ;GET THE RENUMBER INCREMENT
TRNE FL,READOF ;NOT PERMITTED IN READ ONLY
NERROR ILC
TRNE FL,NUMF ;WAS IT A NUMBER
CAMN T1,[ASCID /00000/] ;NO 0 RENUMBER INCR
JRST NUMBC ;NO NUMBER, CHECK FOR COMMA
MOVEM T1,REINC ;THE INCREMENT TO USE
MOVEM T1,INCST ;LINE TO START WITH
PUSHJ P,SCAN ;SCAN PAST NUMBER
NUMBC: CAIN C,"," ;AND CHECK FOR COMMA
JRST NUMB1 ;GET A RANGE
MOVEI T1,1 ;NO RANGE, DO WHOLE FILE
MOVEM T1,LOPG ;FROM PAGE 1
MOVSI T1,1 ;TO IMPOSSIBLY HIGH
MOVEM T1,HIPG
TRZ FL,CNTF ;MAKE SURE THIS IS OFF
JRST NUMBL ;AND CHECK FOR TERMINATOR
NUMB1: PUSHJ P,GET2S ;GET A RANGE
CAIE C,"," ;SEE IF THERE IS A FOURTH ARGUMENT
JRST NUMBL ;NO
PUSHJ P,SCAN ;YES, GET IT
TRNN FL,NUMF ;IS IT A NUMBER?
NERROR ILC ;HE WOULD HAVE BEEN BETTER OFF WITHOUT IT
MOVEM T1,INCST ;USS AS STARTING NUMBER
PUSHJ P,SCAN ;SCAN PAST IT
NUMBL: TRNN FL,TERMF ;ENDS PROPERLY?
NERROR ILC ;LOSE
MOVE T1,LOPG ;GET PLACE TO START
MOVEM T1,DPG
MOVE SINDEX,LOLN ;AND LINE
PUSHJ P,FIND ;GET IT
TRZ FL,LINSN!ORDF ;SET TO NONE SEEN AND NO ORDER ERROR
PUSHJ P,FINDB ;BACK UP AND SEE HOW ORDER LOOKS
JUMPE T1,NUMB5 ;START OF FILE IT MUST BE OK
CAME T1,PGMK ;ALSO IF A PAGE MARK
CAMGE T1,INCST ;OR IF IN CORRECT ORDER
SKIPA
TRO FL,ORDF ;WRONG SET FLAG
NUMB5: PUSHJ P,FIND ;GET THE CORRECT LINE BACK
NUMB2: PUSHJ P,ONMOV ;CHECK RANGE
JRST NUMB3
CAMN T1,PGMK ;PAGE MARK?
JRST NUMB4 ;SPECIAL TREATMENT
MOVE T1,INCST ;GET STAATING NUMBER
MOVE T2,REINC ;AND INCREMENT
TRON FL,LINSN ;WAS A LINE SEEN?
JRST FSTLIN ;NO, FIRST ONE IS SPECIAL
PUSHJ P,ASCIAD ;SKIP THIS THE FFRST TIME
CAMGE T1,REINC ;HAVE WE WRAPED
JRST [RERROR WAR ;TELL HIM HE LOST
MOVE T2,CPG ;PRINT THE PAGE
PUSHJ P,PGPRN
JRST .+1] ;RETURN
FSTLIN: MOVEM T1,INCST ;SAVE FOR NEXT LINE
MOVEM T1,CLN ;AND THE CURRENT LINE
MOVEM T1,(PNTR) ;PUT IT IN
PUSHJ P,FINDN ;GET NEXT
JRST NUMB2 ;AND GO RANGE CHECK
NUMB3: TRNN FL,LINSN ;DONE, WAS THERE SOMETHING THERE?
NERROR NLN ;NO, NULL RANGE ERROR
MOVE T2,CPG ;SET UP CURRENT PAGE
MOVEM T2,CPGL
TRNE FL,ORDF ;WAS THERE AN ORDER ERROR?
NERROR ORDER ;YES, FLAG IT
JUMPE T1,COMND ;CHECK TO SEE IF LOSAGE NOW
CAME T1,PGMK
CAMLE T1,INCST
JRST COMND
NERROR ORDER
NUMB4: ;PAGE MARK
AOS CPG ;NOW ON A HIGHER PAGE
MOVE T1,[ASCID /00000/]
MOVEM T1,CLN ;SET TO FIRST LINE ON PAGE
TRO FL,LINSN ;WE SAW ONE
SETZM INCST ;START OVER ON NUMBERS
PUSHJ P,FINDN ;NOW GET NEXT LINE
JRST NUMB2
BEND NUMBER
SUBTTL NEXT, LAST LINE ROUTINES
BEGIN NXTLIN
↑NXTLIN:MOVE T1,CPGL ;REALLY FIND THE CURRENT LINE
MOVEM T1,DPG
MOVE SINDEX,CLN
PUSHJ P,FIND
CAMN T1,CLN ;DID WE REALLY FIND IT
PUSHJ P,FINDN ;YES, GET NEXT ELSE WE ALREADY HAVE IT
JUMPE T1,[NERROR NLN] ;EOF AND NOT FOUND
NXTL1: CAMN T1,PGMK ;IS THIS A PAGE MARK?
JRST NXTPG ;TREAT SPECIALLY
MOVEM T1,CLN ;SET AS CURRENT
MOVE T1,PNTR ;GET THE CURRENT POINTE
PUSHJ P,OUTLIN ;AND PRINT
JRST COMND ;DONE
NXTPG: AOS T2,CPG ;WE ARE ON THE NEXT PAGE
MOVEM T2,CPGL
PUSHJ P,PGPRN ;TELL HIM
PUSHJ P,FINDN ;FIND A LINE ON IT
JUMPN T1,NXTL1 ;THERE IS ONE THERE, PRINT IT
MOVE T1,[ASCIZ /00000/] ;END OF FILE, SET TO THAT PAGE
MOVEM T1,CLN
JRST COMND
BEND NXTLIN
BEGIN BAKLIN
↑BAKLIN:MOVE T1,CPGL ;FIND CURRENT
MOVEM T1,DPG
MOVE SINDEX,CLN
PUSHJ P,FIND
TRNE FL,BOF ;IF NOT AT START OF FILE
CAME PNTR,BUFP ;OR NOT AT START OF BUFFER
SKIPA
NERROR NLN
BAK1: PUSHJ P,FINDB
CAMN T1,PGMK
JRST PRVPAG ;TELL HIM WE CROSSED A PAGE BOUNDARY
MOVEM T1,CLN ;SET AS CURRENT
MOVE T1,PNTR
PUSHJ P,OUTLIN
JRST COMND
PRVPAG: MOVE T2,CPG
MOVEM T2,CPGL
PUSHJ P,PGPRN
TRNE FL,BOF ;CHECK FOR START OF WORLD
CAME PNTR,BUFP
JRST BAK1 ;OK, BACK UP SOME MOR
MOVE T1,[ASCID /00000/]
MOVEM T1,CLN
JRST COMND
BEND BAKLIN
SUBTTL ROUTINE TO SEARCH FOR SOME STRINGS
BEGIN SEARCH
;DO A SEARCH OF A FILE
↑SEARCH:TLZ FL,ASSMF ;CLEAR ALL FLAGS
SETZM LOLN ;JUST LIKE EVERYONE ELSE HAS TO
SETZM SRCNT ;START WITH ZERO
MOVE T1,[POINT 7,SRBUF] ;SET UP BYTE POINTER
MOVEI T3,SRPNT ;AND POINTER TO BYTE POINTER TABLE
PUSHJ P,SSTRNG ;GET A SEARCH STRING
JRST [SKIPN SRPNT ;WAS STRING SET?
NERROR NSG ;NO, TELL HIM
CAIN C,12
JRST ASSMD1 ;SPECIAL CONTINUE MODE
JRST .+1] ;YES, USE OLD ONE
TLZ FL,NUMSRF!ALTSRF!EXCTSR ;CLEAR FLAGS
TRZ FL2,ZSRF!ZSPA ;CLEAR Z MODE EDIT BITS
PUSHJ P,SCAN ;CHECK FOR WHAT COMES AFTER
TRNN FL,TERMF ;IF TERMINATOR
CAIN C,"," ;OR ,
JRST ASSMDT ;SET UP LIMITS SPECIALLY
CAIE C,"!"
CAIN C,":"
JRST ASSMDT ;LET HIM SPECIFY 2ND HALF OF RANGE
PUSHJ P,GET2 ;ELSE CALL USUAL LIMIT ROUTINE
SRC4: MOVE T1,HILN ;SAVE END OF RANGE
MOVEM T1,SRHILN
MOVE T1,HIPG
MOVEM T1,SRHIPG
CAIE C,"," ;ANY MORE ARGUMENTS?
JRST SRC1 ;NO, CHECK TERMINATOR AND PROCEED
PUSHJ P,SCAN ;YES, SEE WHAT IT IS
TRNN FL,IDF ;SHOULD BE IDENT OR NUMBER
JRST SRC2 ;NOT IDENT, CHECK FOR NUMBER OF SEARCHES
MOVS T1,ACCUM ;GET THE IDENT
CAIN T1,'N ' ;AND FIND OUT WHAT IT IS
TLO FL,NUMSRF
CAIN T1,'Z ';WANT TO EDIT FOUND THING IN Z MODE?
JRST [TRNN FL,DPYF ;YES, CAN WE?
NERROR ILC ; NOT REALLY
TRO FL2,ZSRF ;YES, SET Z MODE BIT
JRST STSRF]
CAIN T1,'A '
STSRF: TLO FL,ALTSRF ;FIRST CHECK FOR A OR N
TRNE FL,READOF ;IF READ ONLY AND ALTER
TLNN FL,ALTSRF
SKIPA
NERROR ILC ;WE DO NOT PERMIT IT
TLNN FL,NUMSRF!ALTSRF ;WAS IT EITHER?
JRST SRC3 ;NO, CHECK E
PUSHJ P,SCAN ;CONTINUE LOOKING
CAIE C,","
JRST SRC1 ;NO MORE ARGUMENTS
PUSHJ P,SCAN ;WELL WHAT KIND IS THIS ONE?
TRNN FL,IDF ;MORE IDENTS?
JRST SRC2 ;NO, MUST BE NUMBER OF SEARCHES
MOVS T1,ACCUM
SRC3: CAIE T1,'E '
NERROR ILC ;NO, HE MUST HAVE MADE A MISTAKE
TLO FL,EXCTSR ;YES, REMEMBER IT
PUSHJ P,SCAN ;AND CHECK FOR MORE
CAIE C,","
JRST SRC1 ;NO MORE
PUSHJ P,SCAN ;ONLY ONE THING IT CAN BE NOW
SRC2: TRNN FL,NUMF
NERROR ILC ;NOPE, LOSE
MOVEM T2,SRCNT ;SAVE AS COUNT OF LINES TO FIND
PUSHJ P,SCAN ;GET TERMINATOR (WE HOPE)
SRC1: TRNN FL,TERMF ;ALLS WELL THAT ENDS WELL
NERROR ILC ;BUT THIS DOSNT
SRCH1A: MOVEI T1,SRPNT ;GET POINTER TO STRINGS
PUSHJ P,CODSR ;AND GENERATE CODE
MOVE T1,LOPG ;GET SET TO HUNT IT
MOVEM T1,DPG
MOVEM T1,SRPG ;FLAG TO SAY IF WE SHOULD PRINT PAGE
MOVE SINDEX,LOLN
PUSHJ P,FIND
TRZ FL,LINSN ;NO LINES YET
ONSRC: PUSHJ P,ONMOV ;CHECK RANGE
JRST ENDSRC ;DONE
TLZE FL,ASSMF ;FIRST TIME AND WANT .+1?
JRST [CAME T1,LOLN ;IS THERE EXACT MATCH?
JRST .+1 ;NO, THIS IS .+1
AOS SVCNT ;PRETEND WE DIDNT SEE IT
JRST SRNXT] ;AND TAKE NEXT
TRO FL,LINSN ;WE SAW ONE
CAMN T1,PGMK ;PAGES ARE SPECIAL
JRST SRCPAG ;SO TAKE GOOD CARE OF THEM
MOVEI T2,SRPNT ;POINTER TO STRINGS
PUSHJ P,COMSRC ;GO SEARCH THIS LINE
JRST SRNXT ;LOSER
WINNER: MOVEM T3,SVCCNT ;SAVE AWAY THE CHARACTER COUNT
MOVE T2,CPG ;GET CURRENT PAGE
CAME T2,SRPG ;AND SEE IF WE SHOULD PRINT IT
PUSHJ P,PGPRN ;YES
MOVE T2,CPG ;NOW SET IT AS CURRENT
MOVEM T2,CPGL
MOVEM T2,SRPG ;ALSO RESET FLAG
MOVE T2,(PNTR) ;ALSO SET LINE
MOVEM T2,CLN
TLNE FL,ALTSRF ;ARE WE GOING TO EDIT?
JRST SRCALT ;YES, GO SET THINGS UP
TLNE FL,NUMSRF ;DO WE WANT ONLY LINE NUMBERS?
JRST SRCNUM ;YES
MOVE T1,PNTR ;GO PRINT LINE
PUSHJ P,OUTLIN
SRNXTC: SOSG SRCNT ;HAVE WE FOUND ENOUGH
JRST COMND ;YES, GIVE UP (WE HAVE SEEN AT LEAST ONE)
SRNXT:
PUSHJ P,FINDN ;GET NEXT LINE TO LOOK A
JRST ONSRC
SRCNUM: MOVE T1,(PNTR) ;PRINT SEQUENCE NUMBER
PUSHJ P,OUTSN
TERPRI (T1)
JRST SRNXTC ;AND GO
ENDSRC: TRZN FL,LINSN ;DID WE SEE ONE?
NERROR NLN ;NULL RANGE
JRST COMND
SRCPAG: AOS CPG ;JUST ADVANCE PAGE COUNTER
JRST SRNXT ;AND PROCEED
SRCALT: TRNE FL2,ZSRF ;IN Z MODE
JRST ZSCALT ; YES, DO IT THAT WAY
PUSHJ P,SETALT ;SET THINGS UP
SKIPLE T2,SVCCNT ;GET COUNT (DO NOT CALL IF ≤0
PUSHJ P,ALTSP ;SPACE OVER CORRECTLY
PUSHJ P,ALTN1 ;GO ALTER
JRST LEVINS ;HE SAID ALTMODE
SRCA1: PUSHJ P,INSED ;INSERT IT
PUSHJ P,FINDN
PUSHJ P,FILLB ;MAKE SURE WE HAVE NOT GOTTEN TOO BIG
MOVE T1,(PNTR) ;GET POINTER BACK
SOSG SRCNT
JRST COMND ;DONE
JRST ONSRC ;GO ON
ZSCALT: PUSHJ P,SETALT ;GET READY
MOVE T2,SVCCNT ;NUMBER TO SPACE OUT
TRO FL2,ZSPA ;SPACE IT ON OUT
PUSHJ P,ZLNN1 ;EDIT THE LINE IN Z MODE
JRST LEVINS ;ALTMODE
JRST SRCA1 ;CONTINUE OR TERMINATE SEARCH
ASSMD1: TROA FL,CNTF ;MARK AS KEEP END OF RANGE
ASSMDT: TRZ FL,CNTF ;JUST IN CASE
TLO FL,ASSMF ;WE ASSUME .+1
MOVE T1,CLN ;SET THINGS UP FOR . TO INFINITY
MOVEM T1,LOLN
MOVEM T1,HILN ;AS GOOD AS ANYTHING WITH THE PAGE WE WILL
MOVE T1,CPGL ;USE
MOVEM T1,LOPG
TRZE FL,CNTF ;KEEP END?
JRST NOSPC ;YES
CAIE C,":" ;IF A : OR !
CAIN C,"!"
JRST HALFSP ;GET THE SECOND HALF (.+1 TO GIVEN)
MOVSI T1,377777 ;GET A LARGE PAGE
MOVEM T1,HIPG
JRST SRC4 ;BACK INTO THINGS
HALFSP: MOVEM T1,HIPG ;SET TOP AS /.
PUSHJ P,GET2HF ;GET THE SECOND HALF
JRST SRC4 ;AND GO
NOSPC: MOVE T1,SRHIPG
MOVEM T1,HIPG ;PUT BACK END
MOVE T1,SRHILN
MOVEM T1,HILN
JRST SRCH1A
BEND SEARCH
SUBTTL SUBST (SUBSTITUTE THINGS)
BEGIN SUBST
;ALSO KNOWN AS SUBSTITUTE
↑SUBST: TLZ FL,ASSMF ;DO NOT ASSUME ANYTHING YET
TRNE FL,READOF
NERROR ILC
SETZM LOLN ;A GOOD THING
MOVSI T1,37777 ;SET COUNT LARGE
MOVEM T1,RPCNT
MOVE T1,[POINT 7,R1BUF]
MOVEI T3,R1PNT
PUSHJ P,SSTRNG ;THIS CODE IS JUST LIKE SEARCH
JRST [SKIPE R2PNT ;BOTH STRINGS MUST HAVE BEEN GIVEN
SKIPN R1PNT
NERROR NSG ;ELSE THERE HAS BEEN AN ERROR
CAIN C,12 ;CHECK FOR JUST A CRRET
JRST ASSMD1 ;AND DO A CONTINUE
JRST NOSTR] ;THERE IS NO STRING
MOVE T1,[POINT 7,R2BUF] ;GET STRING TO REPLACE BY
MOVEI T3,R2PNT
PUSHJ P,SSTRNG
JRST [CAIN C,12
JRST [PUSH P,[.] ;SET UP RETURN
JRST RETSTR] ;AND READ MORE (FISRT NULL)
MOVEM T1,R2PNT ;NULL STRING MEANS DELETE
MOVEI T2,0 ;SO SET A REAL NULL STRING
IDPB T2,T1
JRST .+1]
SUBI T3,R2PNT ;GENERATE NUMBER OF REPLACEMENT STRINGS
MOVEM T3,RSTRCT ;AND SAVE FOR LATER
NOSTR: TLZ FL,NOPRN!DECID!EXCTS1 ;CLEAR FLAGS
PUSHJ P,SCAN ;AND START LOOKING FOR MORE JUNK
TRNN FL,TERMF ;NOTHING
CAIN C,"," ;OR JUST A COMMA
JRST ASSMDT ;THEN SEARCH FROM HERE TO ETERNITY
CAIE C,"!" ;HE ONLY WANTS TO GIVE A STOPPING POINT
CAIN C,":"
JRST ASSMDT
PUSHJ P,GET2 ;GO GET A RANGE
REP4: MOVE T1,HILN ;SAVE FOR POSSIBLE CONTINUE
MOVEM T1,RPHILN
MOVE T1,HIPG
MOVEM T1,RPHIPG
CAIE C,"," ;IS THERE MORE?
JRST REP1 ;NO
PUSHJ P,SCAN ;SEE WHAT IT IS
TRNN FL,IDF ;POSSIBLY AN IDENT
JRST REP2 ;NO MAYBE A NUMBER OF TIMES
MOVS T1,ACCUM
CAIN T1,'N '
TLO FL,NOPRN ;SET FOR NO PRINTING
CAIN T1,'D '
TLO FL,DECID ;HE WANTS TO BE ABLE TO DECIDE
TLNN FL,DECID!NOPRN ;IF NEITHER
JRST REP3 ;THEN TRY FOR E SWITCH
PUSHJ P,SCAN ;SEE IF THERE IS MORE
CAIE C,","
JRST REP1 ;END OF LINE
PUSHJ P,SCAN ;LOOK FOR STILL MORE
TRNN FL,IDF
JRST REP2
MOVS T1,ACCUM
REP3: CAIE T1,'E ' ;IS IT THE EXACT SEARCH SWITCH
NERROR ILC ;NO, LOSAGE
TLO FL,EXCTS1
PUSHJ P,SCAN ;ONE LAST TRY
CAIE C,","
JRST REP1 ;GO CHECK TERMINATOR
PUSHJ P,SCAN ;ONLY ONE THING LEFT
REP2: TRNN FL,NUMF
NERROR ILC ;BUT IT WAS NOT
MOVEM T2,RPCNT ;SAVE IT AWAY
PUSHJ P,SCAN
REP1: TRNN FL,TERMF ;ALLS WELL THAT ENDS WELL
NERROR ILC ;BUT NOT THIS ONE
REP1A: MOVEI T1,R1PNT ;GET THE SEARCH CODE
PUSHJ P,CODSR
MOVE T1,LOPG
MOVEM T1,DPG
MOVEM T1,RPPG ;FOR PRINT OUTS
MOVE SINDEX,LOLN
PUSHJ P,FIND ;GET THAT LIN¬
TRZ FL,LINSN ;NOTHING YET
ONREP: PUSHJ P,ONMOV ;CHECK FOR STILL IN RANGE
JRST ENDREP ;FINALLY
TLZE FL,ASSMF ;SHOULD WE START WITH .+1
JRST [CAME T1,LOLN ;IS IT THE ONE WE ASKED FOR
JRST .+1 ;NO, USE IT
AOS SVCNT ;JUST IN CASE A ! TYPE OF RANGE
JRST RPNXT]
TRO FL,LINSN ;THIS LINE IS GOOD ENOUGH
CAMN T1,PGMK
JRST RPPAG ;GO TAKE CARE OF PAGE MARKS
MOVEI T2,R1PNT ;DO THE SEARCH
PUSHJ P,COMSRC
JRST RPNXT
SKIPGE T3 ;PROTECT AGAINS ¬∀ KILLING TAB
IBP ALTP
PUSH P,T3 ;SAVE COUNT OF HOW FAR INTO LINE
MOVE T3,(PNTR) ;SET UP CURRENT LINE
MOVEM T3,CLN
MOVE T3,CPG
MOVEM T3,CPGL
MOVE T2,[XWD LIBUF,LIBUF+1] ;CLEAR IT OUT
SETZM LIBUF
BLT T2,LIBUF+MXWPL+1 ;WE WILL DO REPLACE HERE
MOVE T2,PNTR ;GET THE POINTER TO THE LINE
MOVE T3,(T2) ;PICK UP THE FIRST WORD
MOVEI T4,LIBUF ;THE PLACE TO PUT IT
JRST SALT3 ;TRANSFER
SALT2: SKIPE T3,(T2)
TRNE T3,1 ;IS IT THE END OF THE LINE
JRST SALT1
SALT3: MOVEM T3,(T4) ;PUT IT AWAY
ADDI T4,1
AOJA T2,SALT2
SALT1: SUBI T4,LIBUF ;GET SIZE LINE USED TO BE
MOVEM T4,OCNT
POP P,CCNT ;GET THE NUMBER OF CHRS INTO LINE
SKIPGE CCNT ;MUST BE ≥0
SETZM CCNT
SUBI ALTP,(PNTR) ;CONVERT POINTER TO LIBUF
ADD ALTP,[XWD 70000,LIBUF] ;AND BACK UP ONE
NXTRPL: LDB T1,[POINT 4,-1(T1),12] ;GET STRING NUMBER
CAMLE T1,RSTRCT ;IS IT LARGER
MOVE T1,RSTRCT ;THEN USE LAST
MOVE T1,R2PNT(T1)
MOVSI T4,70000 ;DECREMENT POINTER
ADDM T4,SRCALP
REPSTR: ILDB C,T1 ;GET THE NEXT CHR
JUMPE C,ENDRP ;THE END OF THE REPLACE STRING
CAIN C,"∂" ;DOES HE WANT ONE OF THE PARTIAL THINGS
JRST PARSTR ;YES, GO HANDLE THAT
CAIN C,"≡" ;CHECK FOR QUOTING NEXT CHR
JRST INSQT
PUTSTR: IDPB C,ALTP ;PUT IN THE REPLACEMENT
AOS C,CCNT ;ADVANCE COUNT
CAIL C,MXWPL*5 ;CHECK AGAINST MAX
NERROR LTL ;AND LOSE
JRST REPSTR
ENDRP: MOVE T3,CCNT ;GET COUNT SO SEARCH CAN GO ON
PUSH P,ALTP ;SAVE REPLACE POINTER
PUSH P,SRCALP ;AND THE END OF INPUT POINTER
MOVE ALTP,SRCALP ;CONTINUE FROM HERE
ILDB T1,SRCALP ;SEE WHAT CHAR WE STOPPED ON
CAIE T1,12 ;HAVE WE GONE TOO FAR?
PUSHJ P,COMSRT ;THIS WILL CONTINUE
JRST FINLIN ;ALL DONE WITH MATCHES, FINISH UP
CAIL T3,MXWPL*5 ;ARE THERE TOO MANY?
NERROR LTL
POP P,T2
DOMOV: ILDB C,T2 ;MOVE THE CHRS THAT DID NOT MATCH
CAMN T2,ALTP ;HAVE WE GOTTEN TO THE NEXT MATCH
JRST DONMOV ;YES
IDPB C,(P) ;THE BYTE POINTER IS STILL IN THE STACK
JRST DOMOV
DONMOV: MOVEM T3,CCNT ;PUT THE COUNT BACK IN CORE
POP P,ALTP ;THIS IS NOW THE DEPOSIT POINTER
JRST NXTRPL ;GO DO A REPLACE
FINLIN: POP P,SRCALP ;GET SET TO MOVE TO END
POP P,ALTP
ILDB C,2(P) ;WE JUST HAPPEN TO KNOW ITS STILL THERE
CAIE C,12 ;IF SO WE HAVE EATEN A RETURN
JRST ENDFIN ;ALL IS OK
FINL2: MOVEI C,15
SKIPA ;SO PUT IT IN
ENDFIN: ILDB C,SRCALP
IDPB C,ALTP
AOS CS,CCNT
CAIL CS,MXWPL*5
NERROR LTL
CAIE C,12
JRST ENDFIN ;DONE WHEN WE SEE THE LINE FEED
MOVEI T1,0 ;ZERO OUT REST OF THIS LINE
DOZER: TLNN ALTP,760000 ;POINTER AT END OF LINE?
JRST ZEROD
IDPB T1,ALTP
JRST DOZER
ZEROD: MOVEI ALTP,1-LIBUF(ALTP) ;GET COUNT
MOVEM ALTP,NCNT
TLNE FL,NOPRN ;DID HE WANT PRINTING SUPRESSED
JRST NOPLIN
MOVE T2,CPG ;GET THIS PAGE
CAMN T2,RPPG ;IS IT ONE WE STARTED ON
JRST NOPPRN ;YES, DO NOT PRINT 'PAGE '
MOVEM T2,RPPG ;SAVE FOR NEXT TIME
PUSHJ P,PGPRN
NOPPRN: MOVEI T1,LIBUF ;PRINT THE LINE
PUSHJ P,OUTLIN
TLNN FL,DECID ;DOES HE WANT THE OPTION OF SAYING NO
JRST NOPLIN ;NO, INSERT IT
IFE FULDPX,<MOVEI T1,DDTINB ;READ
CALLI T1,1
LDB T1,[POINT 7,DDTINB,6] ;GET FIRST CHR
MOVEI T2,[ASCIZ /
/] ;GIVE HIM A RETURN
CALLI T2,3>
IFN FULDPX,<TTYUUO 0,T1
ANDI T1,177
TTYUUO 3,[ASCIZ /
/]>
CAIN T1,177 ;DID HE SAY RUBOUT(DO NOT INSERT)?
JRST RPNXT1 ;YES, JUST IGNORE THIS LINE
CAIE T1,"e" ;EITHER CASE
CAIN T1,"E" ;DOES HE WANT OUT
JRST ENDREP ;YES, QUIT
NOPLIN: PUSHJ P,INSED ;ANYTHING ELSE IS OK
PUSHJ P,FINDN ;GET NEXT
PUSHJ P,FILLB ;IN CASE IT GOT LONGER
SOSG RPCNT ;SEE IF OUT OF COUNT
JRST COMND
MOVE T1,(PNTR) ;GET POINTER BACK
JRST ONREP
ASSMD1: TROA FL,CNTF ;MARK AS KEEP END OF RANGE
ASSMDT: TRZ FL,CNTF ;JUST IN CASE
TLO FL,ASSMF ;WE ASSUME .+1
MOVE T1,CLN
MOVEM T1,LOLN ;SET FOR HERE TO ETERNITY
MOVEM T1,HILN
MOVE T1,CPGL
MOVEM T1,LOPG
TRZE FL,CNTF ;KEEP END?
JRST NOSPC
CAIE C,":" ;IF A : OR A !
CAIN C,"!"
JRST HALFSP ;GET THE SECOND HALF (.+1 TO GIVEN)
MOVSI T1,377777 ;GET A LARGE PAGE
MOVEM T1,HIPG
JRST REP4 ;ONWARD
HALFSP: MOVEM T1,HIPG ;SET TO AS /.
PUSHJ P,GET2HF ;GET THE SECOND HALF
JRST REP4 ;AND GO
NOSPC: MOVE T1,RPHIPG
MOVEM T1,HIPG
MOVE T1,RPHILN
MOVEM T1,HILN
JRST REP1A
INSQT: ILDB C,T1 ;GET NEXT CHR
JUMPN C,PUTSTR ;MUST NOT BE 0
NERROR IRS ;THIS STRING IS ILLEGAL
PARSTR: MOVEI CS,0 ;FIND OUT THE NUMBER
PARST1: ILDB C,T1 ;GET A CHR
CAIN C,"∂" ;CHECK FOR END
JRST ENDNUM
CAIL C,"0" ;MUST BE A DIGIT
CAILE C,"9"
NERROR IRS
IMULI CS,=10 ;CONVERT
ADDI CS,-"0"(C)
JRST PARST1
ENDNUM: CAILE CS,0
CAMLE CS,ARBCNT ;IS IT IN RANGE
NERROR IRS ;NO SUCH PARTIAL STRING
MOVE T4,[POINT 7,ARBBUF] ;START LOOKING FOR IT
SOJLE CS,FNDRST ;STARTS WITH STRING 1
NXTST: ILDB C,T4
JUMPN C,NXTST ;0 IS END OF A PARTIAL STRING
SOJG CS,NXTST ;LOOK FOR CORRECT STRING
FNDRST: ILDB C,T4 ;NOW INSERT THAT STRING
JUMPE C,REPSTR ;GO FINISH THE REPLACEMENT STRING
IDPB C,ALTP
AOS C,CCNT
CAIL C,MXWPL*5
NERROR LTL
JRST FNDRST
RPNXT1: SOSG RPCNT
JRST COMND
RPNXT:
PUSHJ P,FINDN
JRST ONREP ;CONTINUE LOOKING AT LINES
ENDREP: TRZN FL,LINSN ;WERE THERE ANY?
NERROR NLN
JRST COMND
RPPAG: AOS CPG ;JUST ADVANCE PAGE COUNTER
JRST RPNXT
BEND SUBST
SUBTTL PAGE MARK ROUTINE
BEGIN MARK
;INSERT A PAGE MARK AT DESIGNATED LINE
↑MARK: SETZM HILN ;IN CASE OF /A
TRNE FL,READOF ;NOT PERMITTED IN READ ONLY
NERROR ILC
PUSHJ P,GET1S ;GET ONE LINE/PAGE NUMBER
TRNN FL,TERMF ;CHECK FOR TERMINATOR
NERROR ILC
MOVE T1,HIPG ;GO LOOK FOR IT
MOVEM T1,DPG
MOVE SINDEX,HILN ;AND THE LINE
PUSHJ P,FIND ;GET IT
MOVE T1,CPG
CAME T1,HIPG ;PAGE MUST MATCH
NERROR NSP ;MUST MATCH
AOS T1,CPG ;WILL BE ON HIGHER PAGE WHEN DONE
MOVEM T1,CPGL ;SET UP LOGICAL PAGE
AOS BGPG ;THERE IS NOW ONE MORE
AOS INPG
MOVE T1,[ASCID /00000/]
MOVEM T1,CLN ;FIRST LINE ON THAA PAGE
MOVE T1,PGMK ;PUT A PAGE MARK IN LIBUF
MOVEM T1,LIBUF
MOVE T1,[BYTE (7) 15,15,14] ;TEXT OF A PAGE MARK
MOVEM T1,LIBUF+1
SETZM OCNT ;THIS IS A STRAIGHT INSEET
MOVEI T1,2 ;OF 2 WORDS
MOVEM T1,NCNT
PUSHJ P,INSED ;GO DO IT
PUSHJ P,FINDN ;SINCE FILLB MAY WANT TO DUMP THIS LINE
PUSHJ P,FILLB
JRST COMND ;ALL DONE
BEND MARK
SUBTTL DATA COPY AND TRANSFER ROUTINES
BEGIN COPY
↑TRANS: TLOA FL,TRANFL ;SET AS TRANSFER COMMAND
↑COPY: TLZ FL,TRANFL ;JUST TO MAKE SURE
SETZM HILN ;THIS, TOO MAY PROVE USEFUL
SETZM LOLN ;A GOOD THING TO DO
TRNE FL,READOF ;DO NOT LET HIM IN READ ONLY MODE
NERROR ILC
SETZM SVJRL2 ;NO SECOND JOBREL SAVED
PUSHJ P,GET1S ;GET PLACE TO PUT LINES
MOVE T1,HIPG ;STORE IT AWAY FOR LATER
MOVEM T1,DESTPG
MOVE T1,HILN
MOVEM T1,DESTLN
CAIN C,"←" ;DOES HE WANT TO COME FROM ANOTHER FILE?
JRST ALTFIL ;YES
TLZ FL,COPFIL ;NO, MAKE SURE FLAG IS OFF
COPY1:
CAIE C,"," ;SHOULD BE COMMA EVEN IF FROM ALTFIL
NERROR ILC ;HE MUST SAY WHERE TO PUT IT
COPY1A: PUSHJ P,GET2S ;GO GET PLACE TO FIND LINES
MOVE T1,INCR ;SEV INCREMENT AS CURRENT
MOVEM T1,FINCR
SETZM SINCR ;SET NO SECOND INCREMENT
CAIE C,"," ;CHECK FOR MORE ARGUMENTS
JRST CKTERM ;NO, LOOK FOR TERMINATOR
PUSHJ P,SCAN
CAME T1,[ASCID /00000/] ;AVOID 0 INCREMENTS
TRNN FL,NUMF ;SHOULD BE INCREMENT, MUST BE NUMBER
NERROR ILC
MOVEM T1,FINCR
PUSHJ P,SCAN
CAIE C,","
JRST CKTERM
PUSHJ P,SCAN
CAME T1,[ASCID /00000/]
TRNN FL,NUMF
NERROR ILC
MOVEM T1,SINCR
PUSHJ P,SCAN
CKTERM: TRNN FL,TERMF
NERROR ILC ;DID NOT END PROPERLY, LOSE
SETOM NLIN1 ;LINES ON FIRST PAGE
SETZM NLIN2 ;LINES ON LAST PAGE
TLO FL,ISCOP ;SO WE WILL DO SPECIAL RESET IF ERROR
MOVE ALTP,JOBREL ;SET UP SAVE POINTER
MOVEM ALTP,SVJRL ;SO WE CAN RESET IT
MOVEI T1,2000(ALTP) ;ASK FOR ANOTHER 1K
CALLI T1,11
NERROR NEC ;ALL OUT, GIVE UP
HRLI ALTP,-2000 ;SET COUNT OF HOW MUCH IS THERE
SETZM LSTPG ;HAVE SEEN NO PAGES YET
MOVE T1,LOPG ;LOOK FOR SOURCE
MOVEM T1,DPG
MOVE SINDEX,LOLN
PUSHJ P,FIND
TRZ FL,LINSN ;AND NO LINES
TLNN FL,TRANFL ;IS THIS A TRANSFER COMMAND?
JRST GOCOP ;NO, IGNORE ALL THIS SPECIAL STUFF
HRRZM ALTP,STARTD ;SAVE THE START OF DELETED CODE
HRRZM ALTP,ENDD ;AND THE END
MOVE T1,CPG ;GET THE PAGE ON WHICH DELETION STARTS
MOVEM T1,TRANST ;AND SAVE IT
SKIPN -1(PNTR) ;ARE WE AT THE START OF THE BUFFER
TRNN FL,BOF ;AND OF THE WORLD
SKIPA
JRST BEGFIL ;YES, DO NOT LOOK BACK
PUSHJ P,FINDB ;GET THE PREVIOUS LINE
CAMN T1,PGMK ;A PAGE IS SPECIAL
JRST SPCPG
MOVEM T1,BOTLIN ;SAVE IT FOR LATER
PUSHJ P,FINDN ;GO FORWARD AGAIN
JRST GOCOP
SPCPG: SKIPE LOLN ;DO WE INTEND TO ABSORD THIS ONE
JRST BEGFIS ;MOVE FORWARD AND RECORD
SKIPN -1(PNTR) ;CHECK FOR START OF WORLD AGAIN
TRNN FL,BOF
SKIPA
JRST BEGFIS
PUSHJ P,FINDB ;BACK UP
AOS CPG ;FIX PAGE COUNT
PUSH P,T1 ;SAVE THAT LINE
PUSHJ P,FINDN
PUSHJ P,FINDN ;AND GO BACK WHERE WE BELONG
POP P,T1 ;GET LINE NUMBER BACK
CAMN T1,PGMK ;THERE'S THAT PAGE AGAIN
JRST BEGFIA
MOVEM T1,BOTLIN ;SAVE LINE NUMBER
JRST GOCOP
BEGFIS: AOSA CPG
BEGFIA: AOSA CPG
BEGFIF: PUSHJ P,FINDN
BEGFIL: SETOM BOTLIN ;A VERY SMALL NUMBER
GOCOP: SETZM PGDELS ;TOTAL NUMBER OF PAGES DELETED IS 0
SKIPE LOLN ;DID HE ASK FOR THE WHOLE PAGE
JRST NOISTP ;NO
MOVE T1,PGMK ;YES, PUT IN THE PAGE MARK
MOVEM T1,1(ALTP)
MOVE T1,[BYTE (7) 15,15,14]
MOVEM T1,2(ALTP)
HRRZM ALTP,LSTPG
ADD ALTP,[XWD 2,2]
SETZM NLIN1 ;NO LINES ON FIRST PAGE
TLNN FL,TRANFL ;IS THIS A TRANSFER
JRST NOISTP ;NO, START TRANSFER OF DATA
MOVE T1,CPG ;CHECK TO SEE IF WE SHOULD REALLY DELETE
CAIN T1,1 ;NOT IF PAGE 1
JRST RSTSTP
PUSHJ P,FINDB ;GET THAT PAGE
SETZM NCNT ;DELETE
MOVEI T1,2
MOVEM T1,OCNT
PUSHJ P,INSED
PUSHJ P,FINDN1 ;MAKE SURE WE ARE AT THE LINE WE WERE AT
AOS CPG ;KEEP COUNT STRAIGHT
AOSA PGDELS ;ONE DELETED
RSTSTP: HRRZM ALTP,STARTD ;RESET START IF NONE DELETED
HRRZM ALTP,ENDD ;RESET END
NOISTP: MOVE T1,(PNTR) ;MAKE SURE WE HAVE THAT JUNK BACK
ONCOPY: PUSHJ P,ONMOV ;STILL IN RANGE?
JRST ENDCOP ;NO, START INSERTING
TRO FL,LINSN ;WE SAW ONE
CAMN T1,PGMK ;IS IT A PAGE?
JRST MOVPG ;YES, TREAT SPECIAL
MOVLIN: MOVE T1,PNTR ;START TRANSFER
MOVE T2,(T1) ;PICK UP FIRST WORD (SEQ NUM)
MOVEM T2,LSTLN ;SAVE FOR INC CALC
TRLIN: MOVEM T2,1(ALTP) ;PUT LINE AWAY
AOBJP ALTP,RESTCR ;NEED MORE CORE?
TRLIN1: SKIPN T2,1(T1) ;END OF LING?
JRST NXTLIN
TRNN T2,1
AOJA T1,TRLIN ;NO MOVE NEXT WORD
NXTLIN: TLNN FL,TRANFL ;IS THIS TRANSFER?
JRST NXTLCP ;NO, DON'T DELETE
HRRZM ALTP,ENDD ;SAVE END OF DELETED TEXT
SETZM NCNT
SUBI T1,-1(PNTR) ;GET LENGTH
MOVEM T1,OCNT
PUSHJ P,INSED
PUSHJ P,FINDN1 ;MAKE SURE A LINE IS THERE
SKIPA ;SKIP THE FINDN
NXTLCP: PUSHJ P,FINDN ;YES, GET NEXT
AOS NLIN2 ;ONE MORE LINE
JRST ONCOPY
MOVPG: AOS CPG ;WE ARE ON NEXT PAGE
MOVE T1,NLIN2
SKIPGE NLIN1 ;PUT ON FIRST PAGE IF NOT SOME ALREADY THERE
MOVEM T1,NLIN1
SETZM NLIN2
HRRZM ALTP,LSTPG ;SAVE RECORD OF WHERE SEEN
AOS PGDELS ;RECORD ONE MORE PAGE DELETED
JRST MOVLIN ;NOW MOVE IT
RESTCR: MOVE T2,JOBREL ;GET END
ADDI T2,2000
CALLI T2,11 ;GET MORE
NERROR NEC
HRLI ALTP,-2000
JRST TRLIN1 ;AND CONTINUE
ENDCOP: TRNN FL,LINSN ;WERE THERE ANY THERE?
NERROR NLN ;NO LOSE
SETZM 1(ALTP) ;MAKE SURE THERG IS AN END FLAG THERE
TLZE FL,COPFIL ;ARE WE COMMING OFF A FILE
PUSHJ P,RSCOP ;YES, RESET POINTERS
MOVE T1,DESTPG ;LOOK FOR DESTINATION
MOVEM T1,DPG
TLNN FL,TRANFL ;IS IT A TRANSFER?
JRST DOINS1 ;NO, PUT THE COPIED TEXT IN
SETZM PGINSD ;NO EXTRA PAGE MARK INSERTED YET
SKIPN T2,(PNTR) ;ARE WE AT EOF
JRST NOPGIN ;YES, DO NOT INSERT A PAGE MARK
CAME T2,PGMK ;ALSO NOT IF PAGE MARK
CAMLE T2,BOTLIN ;OR GREATER THAN LINE LEFT OVER
SKIPA
SETOM PGINSD ;WE WILL HAVE TO INSERT ONE
NOPGIN: MOVN T2,PGDELS ;GET MINUS NUMBER OF PAGES DELETED
SUB T2,PGINSD ;ONE LESS IF A PAGE MARK INSERTED
CAMGE T1,TRANST ;(T1 HAS DEST. PAGE) IF SMALLER THAN START
JRST DOSUB ;EVERYTHING IS OK
CAMN T1,TRANST ;IS IT SAME?
JRST DSEQTR ;SPECIAL CHECK REQUIRED
CAMGE T1,CPG ;INSIDE RANGE DELETED?
NERROR ITD ;LOSE BIG
CAMN T1,CPG ;SAME AS TOP PAGE?
JRST DSEQCP
ADDM T2,DESTPG ;ADJUST PGE WE ARE TO FIND
ADDM T2,DPG
DOSUB: ADDM T2,CPG ;ADJUST FOR REMOVED PAGES
ADDM T2,INPG
ADDM T2,BGPG
SKIPN PGINSD ;SEE IF WE WANT TO INSERT ONE
JRST DOINS1
MOVE T1,PGMK
MOVEM T1,LIBUF
MOVE T1,[BYTE (7) 15,15,14]
MOVEM T1,LIBUF+1
SETZM OCNT
MOVEI T1,2
MOVEM T1,NCNT
PUSHJ P,INSED
PUSHJ P,FINDN ;ADVANCE OVER IT
PUSHJ P,FILLB ;IN CASE OF OVERFLOW
MSG (T1,<PAGE MARK INSERTED TO PREVENT ORDER ERROR>)
JRST DOINS1
ALLSAM: SKIPN LOLN
SKIPE PGINSD ;IF DID NOT DELETE PAGE OR INSERTED ONE
JRST DOSUB ;ALL OK
SKIPE T1,(PNTR) ;ELSE MUST BE IN UPPER PART
CAMN T1,PGMK
NERROR ITD ;THERE IS NO UPPER PART
CAMLE T1,DESTLN
NERROR ITD
SOS T1,DESTPG ;THIS WILL BE ON A LOWER PAGE
MOVEM T1,DPG
JRST DOSUB
DSEQTR: CAMN T1,CPG ;IS IT ALL ON SAME PAGE?
JRST ALLSAM ;YES, SPECIAL CHECKING
SKIPN LOLN ;DID WE START WITH A PAGE
NERROR ITD ;YES, LOSE
SKIPE PGINSD ;WAS THERE A PAGE INSERTED?
JRST DOSUB ;YES, ALL OK
SKIPE T1,(PNTR) ;FIND OUT WHAT THE NEXT LINE IS
CAMN T1,PGMK
JRST DOSUB ;THIS WILL BE OK
CAMG T1,DESTLN ;SEE IF WE ARE IN TROUBLE
NERROR ITD
JRST DOSUB ;OK
DSEQCP: SKIPE PGINSD ;WAS ONE INSERTED
JRST AOSTRA ;SET PAGE PROPERLY
MOVE T1,DESTLN
CAMG T1,BOTLIN
NERROR ITD
SKIPA T1,TRANST
AOSTRA: AOS T1,TRANST
MOVEM T1,DESTPG
MOVEM T1,DPG ;ALSO SET THIS
JRST DOSUB
DOINS1: MOVE SINDEX,DESTLN
PUSHJ P,FIND
MOVE T1,CPG
CAME T1,DESTPG ;PAGES MUST MATCH
JRST [TLNN FL,TRANFL
NERROR NSP
MOVE T1,PGMK
MOVEM T1,LIBUF
MOVE T1,[BYTE (7) 15,15,14]
MOVEM T1,LIBUF+1
SETZM OCNT
MOVEI T1,2
MOVEM T1,NCNT
PUSHJ P,INSED
PUSHJ P,FINDN
PUSHJ P,FILLB
AOS CPG
AOS INPG
AOS BGPG
MSG (T1,<TEXT INSERTED AT END OF FILE>)
MOVE T1,CPG
JRST .+1]
MOVEM T1,CPGL ;SET THIS AS CURRENT PAGE
MOVE T1,DESTLN ;GET THE PAGE NUMBER TO PUT OUT
MOVEM T1,CLN ;AND THIS AS CURRENT LINE
MOVEM T1,SVLNUM
MOVE ALTP,SVJRL ;POINT TO START OF LINES TO COPY
TLZ FL,TRANFL ;THIS FLAG NO LONGER NEEDED
SKIPE T3,(PNTR) ;GET NEXT LINE AFTER THE INSERT
CAMN T3,PGMK
JRST [MOVEI T1,=100000 ;USE HIGH NUMBER IF NONE THERE
JRST SETHI]
PUSHJ P,NUMCON ;CONVERT ASCID TO NUMBER
SETHI: MOVEM T1,HIGH1 ;SAVE FOR LATER
MOVE T3,DESTLN ;GET NUMBER OF FIRST LINE TO BE INSERTED
PUSHJ P,NUMCON
MOVEM T1,DESTN ;SAVE IT TOO
SKIPGE NLIN1 ;DID WE SEE ANY PAGE MARKS?
JRST ONSET ;NO, ONLY ONE INC TO WORRY ABOUT
SKIPE SINCR ;WAS A SECOND INCREMENT GIVEN?
JRST DOSINC ;YES
SKIPE T3,(PNTR)
CAMN T3,PGMK ;ARE THERE ANY LINES AFTER IT
JRST OKINC2 ;NO, OK TO LEAVE LINES AS THEY ARE
DOSINC: MOVE T1,HIGH1 ;CALCULATE MAX POSSIBLE INCREMENT
AOS T2,NLIN2 ;WICH WILL NOT RUIN ORDER
IDIV T1,T2
JUMPE T1,ORDSEC ;THERE IS NO POSSIBLE GOOD ONE
CAIL T1,=100000 ;A VERY LARGE ONE IS POSSIBLE
JRST OKINC2 ;SO JUST USE THE ONE GIVEN
PUSHJ P,ASCON ;CONVERT TO ASCID
SKIPN SINCR ;WAS THERE AN INC GIVEN?
JRST [MOVE T1,LSTLN ;GET THE HIGHEST LINE PICKED UP
CAML T1,(PNTR) ;SEE IF IT IS OK
JRST ONST3 ;NO
JRST OKINC2]
CAML T3,SINCR ;SEE IF ONE GIVEN IS OK
JRST OKINC2 ;YES
ONST3: MOVEM T3,SINCR ;NO, STORE CALCULATED
ONST2: MOVEM T3,PRNTO2 ;AND TELL HIM
IFE FULDPX,<MOVEI T1,ASCIZ2
CALLI T1,3>
IFN FULDPX,<TTYUUO 3,ASCIZ2>
OKINC2: MOVEI T1,=100000 ;FIND A SUITABLE FIRST INCREMENT
SUB T1,DESTN
SKIPN NLIN1 ;WERE THERE ANY?
JRST INSL2 ;NO, ALL IS OK
IDIV T1,NLIN1 ;GET USABLE ONE
JUMPE T1,ORDCP2 ;NONE POSSIBLE
CAIL T1,=100000
JRST INSL2 ;ALL OK
PUSHJ P,ASCON ;CONVER
CAML T3,FINCR ;IS ONE GIVEN SMALLER?
JRST INSL2 ;YES, ALL OK
MOVEM T3,FINCR
JRST ONST1 ;LET HIM KNOW
ONSET: SKIPG NLIN2 ;WERE THERE ANY?
JRST INSL2 ;ALL OK
MOVE T1,HIGH1
SUB T1,DESTN
IDIV T1,NLIN2 ;CALCULATE INCREMENT
JUMPE T1,ORDCOP ;NONE POSSIBLE
CAIL T1,=100000
JRST INSL2 ;VERY BIG, ALL OK
PUSHJ P,ASCON
CAML T3,FINCR ;IS ONE GIVEN SMALLER?
JRST INSL2
MOVEM T3,FINCR
ONST1: MOVEM T3,PRNTO1 ;PUT IN IN PRINT POSITION
IFE FULDPX,<MOVEI T1,ASCZ1
CALLI T1,3>
IFN FULDPX,<TTYUUO 3,ASCZ1>
JRST INSL2 ;HE HAS BEEN TOLD
ORDCP2: SKIPA T3,[ASCII /WAR /]
ORDCOP: MOVE T3,[ASCII /ORDER/]
JRST ONST1
ORDSEC: MOVE T3,[ASCII /ORDER/]
JRST ONST2
↑ASCON: MOVSI T3,400000 ;WILL BECOME LOW ORDER BIT
ASCO2: IDIVI T1,=10
ADDI T2,"0"
LSHC T2,-7
TRNN T3,1 ;HAS IT GOTTEN THERE?
JRST ASCO2
POPJ P,
NUMCON: MOVEI T1,0
TRZ T3,1 ;GET RID OF LOW ORDER BIT
NUMC1: MOVEI T2,0
LSHC T2,7
IMULI T1,=10
ADDI T1,-"0"(T2)
JUMPN T3,NUMC1
POPJ P,
INSLN: MOVE T2,FINCR ;GENERATE NEW SEQUENCE NUMBER
SKIPN T1,SVLNUM ;BUT ONLY IF WE ARE SUPPOSED TO
JRST INSL2
PUSHJ P,ASCIAD
MOVEM T1,SVLNUM ;PUT EITHER NGW OR 0 BACK
INSL2: SETZM LIBUF ;ZERO OUT PLACE TO PUT LINE
MOVE T1,[XWD LIBUF,LIBUF+1]
BLT T1,LIBUF+MXWPL+1
MOVEI T1,LIBUF ;SET UP OUTPUT POINTER
SKIPN T2,1(ALTP) ;AT END?
JRST INSDON ;FINISHED
INS1: MOVEM T2,(T1) ;PUT IT AWAY
ADDI ALTP,1 ;NEXT
SKIPN T2,1(ALTP) ;CHECK FOR END OF LING
JRST DOINS
TRNN T2,1 ;BY EITHER METHOD
AOJA T1,INS1 ;GO ON WITH TRANSFER
DOINS: SUBI T1,LIBUF-1 ;GET COUNT
MOVEM T1,NCNT ;AND SET AS NEW
SETZM OCNT ;OLD IS ZERO
MOVE T1,LIBUF ;GET SEQ NUM
CAMN T1,PGMK ;CHECK FOR PAGE
JRST INSPG ;AND DO SPECIAL
SKIPN T1,SVLNUM ;IF A NON-ZERO NUMBER THEN REPLACE
MOVE T1,LIBUF
MOVEM T1,LIBUF
NOINCR: MOVEM T1,CLN ;SET AS CURRENV LINE
PUSHJ P,INSED ;INSERT IT
PUSHJ P,FINDN ;GET NEXT
PUSHJ P,FILLB ;AND DUMP IF NEEDED
JRST INSLN ;GO PUT IN MORE
INSPG: AOS T3,CPG ;WE ARE ON THE NEXT PAGE
MOVEM T3,CPGL ;SET AS CURRENV
MOVE T1,[ASCID /00000/] ;SET TO SAY LINE 0
AOS BGPG ;ONE MORE PAGE IN FILE
AOS INPG
SETZM SVLNUM ;DO NOT DO ANY MORE SEQUENCE REPLACEMENT
MOVEI T2,-2(ALTP) ;SINCE WE HAVE ALREADY GONE PAST
CAMN T2,LSTPG ;UNLESS STARTING LAST PAGE
SKIPN T3,SINCR ;ANF SECOND SEQUENCE NUMBER GIVEN
JRST NOINCR
MOVEM T3,FINCR ;SET UP INCREMENT
MOVEI T3,1 ;AND RESTART NUMBERING
MOVEM T3,SVLNUM
JRST NOINCR
INSDON:
↑COPDON:RELEASE ALTDV,0 ;JUST FOR GOOD MEASURE
TLZE FL,COPFIL ;ARE WE COPYING FROM A FILE (ERRORS ONLY)
PUSHJ P,RSCOP ;YES, CLEAN UP POINTERS
TLZ FL,ISCOP ;RESET COPY FLAG
TLNN FL,TRANFL ;IF TRANSFER, WE MUST REINSERT
JRST COPD1 ;NO
MOVE ALTP,STARTD
REINXT: MOVEI T1,LIBUF
CAMN ALTP,ENDD
JRST COPD1 ;ALL DONE
MOVE T2,1(ALTP)
JRST REINWD
REINS: MOVE T2,1(ALTP)
CAME ALTP,ENDD
TRNE T2,1
JRST ENDLIN ;DONE WITH THIS LINE
REINWD: MOVEM T2,(T1)
ADDI T1,1
AOJA ALTP,REINS
ENDLIN: SETZM OCNT
SUBI T1,LIBUF
MOVEM T1,NCNT
PUSHJ P,INSED ;INSERT LINE
PUSHJ P,FINDN
PUSHJ P,FILLB ;IN CASE OF OVERFLOW
JRST REINXT
COPD1: SKIPN T1,SVJRL2 ;USE THIS IF SET
MOVE T1,SVJRL ;ELSE THIS
CALLI T1,11 ;TO RESTORE PROPER AMOUNT OF CORE
ERROR ICN ;THIS SHOULD NEVER HAPPEN
JRST COMND ;FINISH UP
ALTFIL: TLNE FL,TRANFL ;ANOTHER FILE IS NOT LEGAL IN TRANSFER
NERROR ILC
PUSHJ P,SCAN
PUSHJ P,READNM
NERROR ILC
SKIPE RSW ;THIS SWITCH NOT ALLOWED
NERROR ILC
DONNAM: MOVE T1,JOBREL ;SET THINGS UP
MOVEM T1,SVJRL2
ADDI T1,4000 ;ASK FOR 1 K FOR BUFFERS
TLO FL,ISCOP ;TELL THE WORLD WHAT WE HAVE DONE
CALLI T1,11 ;IS IT THERE?
NERROR NEC
MOVE T1,SVJRL2 ;POINT BUFFERS TO RIGHT PLACE
MOVEM T1,JOBFF
INIT ALTDV,14 ;GET IT
SIXBIT /DSK/
ALTBF
NERROR DNA ;MAYBE ITS HEREDITARY
PUSH P,NAMI+3 ;SAVE THIS BEFORE THE LOOKUP DESTROYS IT
LOOKUP ALTDV,NAMI
NERROR FNF
INBUF ALTDV,2 ;GET BUFFER SPACE
MOVE T1,ORGPPN ;SAVE OLD NAMES
EXCH T1,(P) ;AND REPLACE BY NEW
MOVEM T1,ORGPPN ;IN CASE WE HAVE TO BACK UP
MOVE T1,NAMI
PUSH P,ORGNAM
MOVEM T1,ORGNAM
HLLZ T1,NAMI+1
PUSH P,ORGEXT
MOVEM T1,ORGEXT
MOVE T1,JOBREL
SUBI T1,2*MXWPL+2 ;SET UP THE VARIOUS POINTERS
PUSH P,FILPT ;SEE STPT FOR MORE INFO
MOVEM T1,FILPT
MOVEI T1,1
PUSH P,CPGL
MOVEM T1,CPGL
MOVE T1,[ASCID /00000/]
PUSH P,CLN
MOVEM T1,CLN
MOVE T1,JOBFF
SETZM (T1)
ADDI T1,1
PUSH P,BUFP
MOVEM T1,BUFP
MOVE T1,JOBREL
SUB T1,BUFP
MOVE T2,T1
SUBI T2,MXWPL+1
PUSH P,MAXWC
MOVEM T2,MAXWC
ASH T1,-1
PUSH P,HLFWC
MOVEM T1,HLFWC
MOVEI T1,1
PUSH P,CPG
PUSH P,INPG
MOVEM T1,CPG
MOVEM T1,INPG
PUSH P,PNTR
MOVE PNTR,BUFP
PUSH P,SVWD
SETZM SVWD
PUSH P,OLDLIN
SETZM OLDLIN
PUSH P,WC
SETZM WC
MOVSI T1,1
PUSH P,BGPG
MOVEM T1,BGPG
MOVE T1,FL ;SAVE SELECTED FLAGS
AND T1,[XWD TECOF+FSTOPF,READOF!BOF!EOF!EOF2!BGSN]
PUSH P,T1
TRZ FL,EOF!EOF2
TRO FL,READOF!BOF
TLZ FL,TECOF
TLO FL,FSTOPF
MOVEM P,COPDL ;SAVE PDL FOR LATER
TLO FL,COPFIL ;WE ARE USING OTHER FILE POINTERS
PUSHJ P,FILLBF
SKIPN SSW
JRST COPY1
TRNN FL,TERMF ;MUST END HERE
NERROR ILC
TLO FL,SRCOP ;SET THINGS UP
JRST COMND ;AND GO GET COMMANDS
↑DSCOP: TLZ FL,SRCOP ;TURN IT OFF
MSSG (T1,SOURCE LINES=)
SETZM LOLN ;THIS MAY HAVE GOTTEN RESET
SETZM SAVCHR ;CLEAR THINGS OUT
SETZM TIBUF+2 ;CLEAR REST OF INPUT
JRST COPY1A ;GO GET REST OF COMMAND STRING
RSCOP: POP P,T2
MOVE P,COPDL ;GET PDL BACK
POP P,T1
TRZ FL,READOF!BOF!EOF!EOF2!BGSN ;RESTORE SELECTED FLAGS
TLZ FL,TECOF!FSTOPF
IOR FL,T1
POP P,BGPG
POP P,WC
POP P,OLDLIN
POP P,SVWD
POP P,PNTR
POP P,INPG
POP P,CPG
POP P,HLFWC
POP P,MAXWC
POP P,BUFP
POP P,CLN
POP P,CPGL
POP P,FILPT
POP P,ORGEXT ;GET NAMES BACK
POP P,ORGNAM
POP P,ORGPPN
JRST (T2) ;NOW RETURN
↑COPGET:SOSG ALTBF+2 ;GET A WORD FROM COPY FILE
JRST GETDO
GETWD1: ILDB T3,ALTBF+1
JUMPE T3,COPGET
POPJ P,
GETDO: INPUT ALTDV,0
STATO ALTDV,760000
JRST GETWD1
STATZ ALTDV,740000
ERROR DIE
TRO FL,EOF
MOVEI T3,0
POPJ P,
↑CKTEC2:SETSTS ALTDV,0
MOVSI T3,(<POINT 7,0>)
HLLM T3,ALTBF+1
MOVEI T3,5
IMULM T3,ALTBF+2
AOS ALTBF+2
JRST RDTECO
BEND COPY
SUBTTL PRINT ROUTINE
BEGIN PRINT
↑PRINT: SETZM LOLN ;AS A FLAG IN CASE OF /C OR /A,/C
PUSHJ P,SCAN
CAIE C,"," ;IS THERE A SWITCH?
JRST PRNT5 ;NO
PUSHJ P,SCAN ;YES, GET IT
TRO FL2,SUPN ;SUPPRESS LINE NUMBERS
PUSHJ P,SCAN ;SCAN PAST IT
PRNT5: TRNE FL,TERMF
JRST [MOVE T1,CLN ;MAKE P WITH NO ARGS DO P.!16
MOVEM T1,LOLN
MOVE T1,CPGL
MOVEM T1,LOPG
MOVEI T1,=16
MOVEM T1,SVCNT
TRO FL,CNTF
JRST PRCNT]
PUSHJ P,GET2 ;GET A DOUBLE STRING
CAIE C,"," ;I{S THERE A SWITCH?
JRST PRNT6 ;NO
PUSHJ P,SCAN ;YES, GET IT
TRO FL2,SUPN ;SUPPRESS LINE NUMBERS
PUSHJ P,SCAN ;SCAN PAST
PRNT6: TRNN FL,TERMF ;DID IT END WITH A TERMINATOR
NERROR ILC ;NO, ILLEGAL
PRCNT: TRZ FL,LINSN ;USE THIS AS A FLAG TO CHECK FOR NULL RANGE
↑RPGPRN:MOVE T1,LOPG ;FIND THE FIRST LINE WANTED
MOVEM T1,DPG ;SET IT AS THE ONE WE WANT
MOVE SINDEX,LOLN ;PICK UP THE LINE
PUSHJ P,FIND ;GO GET IT
SKIPE LOLN ;DID WE WANT TO PRINT AN ENTIRE PAGE
JRST PRNT1 ;NO, GO CHECK BOUNDS
MOVE T2,CPG ;WHICH ONE ARE WE ON
MOVEM T2,CPGL
PUSHJ P,PGPRN ;PRINT THE PAGE HEADER
TRO FL,LINSN ;THIS CAN COUNT AS A LINE
PRNT1: PUSHJ P,ONMOV ;CHECK TO SEE IF STILL IN RANGE
JRST EPRNT ;NO, END
TRO FL,LINSN ;WE HAVE SEEN ONE
CAMN T1,PGMK ;IS IT A PAGE MARK?
JRST PRNT3 ;YES, DO SOMETHING SPECIAL
MOVEM T1,CLN
MOVEM T2,CPGL ;SAVE PAGE TOO
MOVE T1,PNTR ;GET THE POINTER TO IT
PUSHJ P,OUTLIN ;AND PRINT
PRNT4: PUSHJ P,FINDN ;GET THE NEXT LINE
JRST PRNT1 ;AND CONTINUE
PRNT3: MOVEM T2,CPGL
TRNN FL2,SUPN ;UNLESS PRINTING A CLEAN COPY,
PUSHJ P,PGPRN ;GO PRINT A PAGE HEADER
AOS CPG
MOVE T2,[ASCID /00000/]
MOVEM T2,CLN ;SET LINE TO FIRST ON THAT PAGE
JRST PRNT4 ;AND CONTINUE
EPRNT: TRZN FL,LINSN ;DID WE PRINT SOMETHING
NERROR NLN ;NO, ERROR
JRST COMND ;YES, RETURN FOR COMMAND
BEND PRINT
SUBTTL LIST ROUTINE
BEGIN LIST
↑LIST: TRZ FL2,SUPN ;ASSUME WE ARE GOING TO LIST LINE NUMBERS
SETZM LOLN ;FOR START OF PAGE
IFN STANSW,< ;REG SPOOLING FEATURE.
;AT STANFORD, "LS" COMMAND LISTS TO A FILE AND SPOOLS IT
SETZM SPOOLR ;ASSUME NOT SPOOLING.
PUSHJ P,GNCH ;GET THE NEXT CHARACTER INTO C
CAIE C,"S"
CAIN C,"s"
SOSA SPOOLR ;SET FLAG AND SKIP
MOVEM C,SAVC ;CHARACTER NOT S. PUSH IT BACK WHERE SCAN
;WILL SEE IT NEXT TIME THRU.
>
PUSHJ P,SCAN ;SCAN THE NEXT STUFF
CAIE C,"," ;IS THERE A SWITCH?
JRST LIST9 ;NO
PUSHJ P,SCAN ;YES, SCAN FOR IT
MOVS T1,ACCUM
CAIE T1,'S ' ;IS IT S?
NERROR ILC ;NO, LOSE
TRO FL2,SUPN ;YES, SUPPRESS LINE NUMBERS
PUSHJ P,SCAN ;AND SCAN PAST IT
LIST9: TRNN FL,TERMF ;JUST A TERMINATOR
JRST LIST7 ;NO, GO LOOK FOR A COMMAND STRING
MOVEI T1,1 ;LIST ENTIRE FILE
MOVEM T1,LOPG
MOVSI T1,1 ;FROM 1 TO IMPOSSIBLY HIGH
MOVEM T1,HIPG
TRZ FL,CNTF ;MAKE SURE THAT THIS FLAG IS OFF
JRST LIST8 ;GO START WORK
LIST7: PUSHJ P,GET2 ;HAVE ALREADY SCANNED, GET 2 NUMBERS
CAIE C,"," ;IS THERE A SWITCH?
JRST LIST10 ;NO
PUSHJ P,SCAN ;YES, SCAN FOR IT
MOVS T1,ACCUM
CAIE T1,'S ' ;IS IT S?
NERROR ILC ;NO, LOSE
TRO FL2,SUPN ;YES, SUPPRESS LINE NUMBERS
PUSHJ P,SCAN ;AND SCAN PAST IT
LIST10: TRNN FL,TERMF ;END OK?
NERROR ILC
CAIN C,200
TRO FL2,SUPN ;SUPPRESS LINE NUMBERS IF ALTMODE
LIST8: TRZ FL,LINSN ;NONE SEEN YET
MOVEI T1,LPTBUF ;GET SET TO INIT THE LPT
MOVEM T1,JOBFF
COMMENT /REG/
COMMENT/WE USE OPEN INSTED OF INIT SO WE CAN SELECT
OUR OUTPUT DEVICE AT RUN TIME.
/
IFE STANSW,<MOVEI T1,100 ;USING MODE 100>
IFN STANSW,<MOVEI T1,1>
MOVEM T1,OPENBK
MOVSI T1,'LPT'
SKIPE SPOOLR
MOVSI T1,'DSK'
MOVEM T1,OPENBK+1
MOVSI T1,LOBUF
MOVEM T1,OPENBK+2
OPEN LPT,OPENBK
NERROR UNA ;CAN NOT GET IT
IFN STANSW,< ;SPOOLING FEATURE
SKIPN SPOOLR
JRST LIST01
MOVE T1,ORGNAM
MOVEM T1,OPENBK
MOVSI T1,'$$/' ;Stopgap Spooled Listing
MOVEM T1,OPENBK+1
LST002: HLRZ T1,OPENBK+1
ADDI T1,1
HRLZM T1,OPENBK+1
SETZM OPENBK+2
SETZM OPENBK+3
LOOKUP LPT,OPENBK
JRST .+2
JRST LST002
HRLZM T1,OPENBK+1
SETZM OPENBK+2
SETZM OPENBK+3
ENTER LPT,OPENBK
NERROR UNA ;HAVE TO GIVE SOME SORT OF ERROR
LIST01:
> ;END REG SPOOLING FEATURE.
OUTBUF LPT,1 ;ASK FOR ONE BUFFER
MOVEI T2,LPTBUF ;FIND OUT HOW BIG IT IS
EXCH T2,JOBFF
SUBI T2,LPTBUF ;THE SIZE
MOVEI T1,203*2+1 ;THE SPACE RESERVED FOR IT
IDIV T1,T2 ;GET NUMBER THAT WILL FIT THERE
OUTBUF LPT,(T1) ;AND ASK FOR THAT MANY
MOVE T1,[XWD PGHS,PGHD] ;GET A COPY OF THE BLANK HEADER
BLT T1,PGHD+11
MOVE C,[POINT 7,PGHD,27] ;START TO FILL IT
MOVEI T3,6 ;6 CHRS IN FILE NAME
MOVE T2,ORGNAM ;USE THE ORIGINAL NAME
PUSHJ P,PRTSX ;PUT IT IN THE HEADER
SKIPN T2,ORGEXT ;GET THE EXTENSION
JRST LIST1 ;NONE THERE, IGNORE
MOVEI T1,"." ;A DOT BETWEEN
IDPB T1,C
MOVEI T3,3 ;ONLY 3 CHRS HERE
PUSHJ P,PRTSX
LIST1: MOVE ALTP,[POINT 7,PGHD+3] ;TIME+DATE (ALTP IS FREE)
CALLI T1,14 ;GET DATE
IDIVI T1,=31 ;LEAVES DAY IN T2
PUSH P,T2 ;SAVE IT
IDIVI T1,=12 ;LEAVES MONTH IN T2 YEAR IN T1
EXCH T1,(P) ;INVERT ORDER OF DAY AND YEAR
PUSH P,T1 ;AND SAVE
MOVEI T1,1(T2) ;GET MONTH (MUST ADD 1)
MOVEI T3,HDOCH ;PLACE FOR DECPR TO PUT THINGS
PUSHJ P,DECPR
MOVEI T1,"/" ;SEPERATE
IDPB T1,ALTP
POP P,T1 ;THE DAY
ADDI T1,1
PUSHJ P,DECPR ;PRINT IT TOO
MOVEI T1,"/"
IDPB T1,ALTP
POP P,T1 ;THE YEAR
ADDI T1,=64 ;CONVERT TO REAL YEAR
PUSHJ P,DECPR
IBP ALTP ;SKIP OVER A SPACE
CALLI T1,23 ;GET THE TIME
IDIVI T1,=60000 ;CONVERT TO MINUTES
IDIVI T1,=60 ;NOW TO HOURS
PUSH P,T2 ;SAVE MINUTES
PUSHJ P,DECPR ;PRINT
MOVEI T1,":"
IDPB T1,ALTP
POP P,T1 ;GET MINUTES BACK
MOVEI T2,"0" ;MAKE SURE THERE ARE 2 DIGITS
CAIG T1,=9
IDPB T2,ALTP
PUSHJ P,DECPR
SETZM LOGPG ;LOGICAL PAGE TO 0
MOVE T1,LOPG ;GET SET TO PRINT
MOVEM T1,DPG
MOVE SINDEX,LOLN
PUSHJ P,FIND ;GO FIND IT
SETZM LSTCNT ;COUNT OF NUMBER OF LINES PER PAGE
LST2: PUSHJ P,ONMOV ;CHECK RANGE
JRST LST6 ;FINISH UP
TRO FL,LINSN ;YEP, WE HAVE SEEN ONE
CAMN T1,PGMK ;CHECK FOR PAGE MARK AND HANDLE SPECIAL
JRST LST4
MOVEM T1,CLN ;THE CURRENT LINE
MOVEI T2,0 ;COUNT OF NUMBER OF CHRS SEEN
SOSG LSTCNT ;CHECK TO SEE IF RUN OUT
PUSHJ P,HDPRNT ;GO PRINT HEADING
LST2A: MOVE T1,PNTR ;GET THE POINTER
TRNN FL2,SUPN ;DO WE WANT TO SUPPRESS LINE NUMBERS?
JRST LST3A ;NO
AOS T1 ;YES, SKIP A WORD
HRLI T1,(<POINT 7,0,6>) ;AND A CHARACTER
ADDI T2,6 ;AND TELL PEOPLE WE HAVE DONE SO
JRST LST3 ;BEFORE GOING ON OUR WAY
LST3A: HRLI T1,(<POINT 7,0>) ;AND SET UP BYTE POINTER
LST3: ILDB C,T1 ;GET CHR
IFE STANSW, <SKIPL C,LPTAB(C) ;GET LPT EQUIV AND CHECK FOR SPECIAL>
IFN STANSW, <SKIPL LPTAB(C)>
JRST SPHD
IFE STANSW,< TLNN C,200000
JRST LST5
PUSH P,C
MOVEI C,"?"
PUSHJ P,POCHR
ADDI T2,1
POP P,C
LDB C,[POINT 7,CTBL(C),10]>
LST5: PUSHJ P,POCHR ;PRINT IT
AOJA T2,LST3 ;COUNT AND CONTINUE
SPHD: CAIN C,12 ;LINE FEED IS END OF LINE
JRST [PUSHJ P,POCHR ;PRINT IT
PUSHJ P,FINDN ;GET NEXT
JRST LST2] ;AND GO
CAIN C,11 ;COUNT SPECIAL FOR TAB
JRST [PUSHJ P,POCHR
ADDI T2,10
ANDCMI T2,7
JRST LST3]
CAIN C,15
JRST [ MOVNI T2,1
JRST LST5]
CAIN C,14
JRST [PUSHJ P,POCHR ;FORM FEED GETS A HEADING
PUSHJ P,HDPRNT
JRST LST3]
CAIN C,"\" ;NEEDS DELETE,DELETE
IFE STANSW, <JRST [MOVEI C,177
PUSHJ P,POCHR
JRST LST5] ;AND AGAIN>
IFN STANSW, <JRST LST5>
CAIE C,13 ;VERT.TAB
ERROR ICN ;CONFUSED
PUSHJ P,POCHR
MOVE T3,LSTCNT
CAIG T3,(%LPP+2)/3
JRST [PUSHJ P,HDPRNT
JRST LST3]
CAIG T3,(2*(%LPP+2))/3
MOVEI T3,(%LPP+2)/3
CAIL T3,(2*(%LPP+2))/3
MOVEI T3,(2*(%LPP+2))/3
MOVEM T3,LSTCNT
JRST LST3
LST4: MOVEI C,14 ;PRINT A FORM FEED
SOSLE LSTCNT ;BUT ONLY IF WE ARE NOT ALREADY THERE
PUSHJ P,POCHR
AOS T1,CPG ;GET PAGE CORRECTLY
MOVEM T1,CPGL
SETZM LOGPG ;ZERO LOGICAL PAGE AGAIN
MOVEI T2,0 ;THIS MUST BE ZERO SO GET IT THAT WAY
PUSHJ P,HDPRNT ;PRINT A HEADER
AOS LSTCNT ;INCREASE BY 1 TO MAKE IT COME OUT RIGHT
PUSHJ P,FINDN ;ADVANCE
JRST LST2 ;AND CONTINUE
LST6: RELEAS LPT,0 ;GET RID OF IT
TRZ FL2,SUPN ;TURN THIS OFF SO * PRINTS
IFN STANSW,< ;SPOOLING FEATURE
SKIPN SPOOLR
JRST LST600
;OPENBK IS KNOWN TO HAVE THE RIGHT NAME AND EXT
;THE RIGHT HALF OF EXT WORD MUST BE SET TO 1,
;FOR DELETE AFTER SPOOLING. I PRESUME THAT
;ALL OTHER BITS SHOULD BE OFF.
;OPENBK+2 AND OPENBK+3 SHOULD BE CLEARED.
MOVEI T1,1
HRRM T1,OPENBK+1
SETZM OPENBK+2
SETZM OPENBK+3
TRNE FL,LINSN ;ANY LINES THERE?
JRST LST599 ;YES. SPOOL THEM
INIT LPT,17 ;NOTHING THERE. DELETE FILE
SIXBIT /DSK/
0
NERROR UNA
LOOKUP LPT,OPENBK ;SEEK FILE
JRST LST598 ;NOT THERE
SETZB T1,T2 ;ZERO 4 WORDS
SETZB T3,T4
RENAME LPT,T1
JFCL
LST598: RELEAS LPT,
JRST LST600
LST599:
PUSHJ P,SPSUB
> ;END SPOOLING FEATURE
LST600: TRNN FL,LINSN ;SKIP IF LINES THERE
NERROR NLN ;NO LINES
MOVE T1,CPG ;SET UP PAGE
MOVEM T1,CPGL
JRST COMND ;AND GET MORE COMMANDS
POCHR: SOSG LOBUF+2 ;ROOM FOR MORE?
OUTPUT LPT,0
CAIL T2,=120 ;END OF LINE?
JRST [ MOVEI T2,0
SOSG LSTCNT
PUSHJ P,HDPRNT
JRST .+1]
IDPB C,LOBUF+1
POPJ P,
HDPRNT: PUSH P,T1 ;SAVE POINTER
TRNE FL2,SUPN ;IF PRETTY PRINTING
JRST HDPR3 ;WE DON'T REALLY WANT TO DO THIS
MOVEI C,15 ;GET TO LEFT OF PAGE
PUSHJ P,POCHR
MOVE T1,[POINT 7,PGHD] ;GET SET TO PRINT HEADER
HDPR1: ILDB C,T1 ;GET A CHARACTER
JUMPE C,HDPR2 ;DONE?
PUSHJ P,POCHR ;PRINT IT
JRST HDPR1 ;CONTINUE
HDPR2: PUSH P,T2 ;SAVE CHARACTER COUNT
MOVE T1,CPG ;GET CURRENT PAGE
MOVEI T3,POCHR ;WHERE TO PRINT IT
PUSHJ P,DECPR ;PRINT
MOVEI C,"-"
PUSHJ P,POCHR
AOS T1,LOGPG ;GET NEXT LOGICAL PAGE
PUSHJ P,DECPR
HDPR3: MOVEI C,15 ;NOW RET AND 2 LFDS
PUSHJ P,POCHR
MOVEI C,12
PUSHJ P,POCHR
PUSHJ P,POCHR
MOVEI T1,%LPP ;RESET LINE COUNT
MOVEM T1,LSTCNT
TRNN FL2,SUPN ;IF IN SUPPRESS MODE WE DID NOT SAVE
POP P,T2 ;GET BACK COUNT OF CHRS
JUMPE T2,TPOPJ1 ;IF 0 THEN ALL OK
MOVE T3,T2 ;GET COPY
MOVEI C," " ;PRINT CORRECT NUMBER OF SPACES
PUSHJ P,POCHR
SOJG T3,.-1
TPOPJ1: POP P,T1 ;RESTORE POINTER
POPJ P,
PRTSX: MOVEI T1,0 ;SET TO RECIEVE A CHR
LSHC T1,6 ;GQT ONE
ADDI T1,40 ;CONVERT
IDPB T1,C ;PUT IN HEADER
SKIPE T2 ;ONLY SPACES LEFT?
SOJG T3,PRTSX ;OR COUNT RUN OUT?
POPJ P, ;RETURN
HDOCH: IDPB C,ALTP ;PUT CHRS FROM DECPR INTO HEADER
POPJ P,
SUBTTL SPOOLER STUFF
IFN STANSW,< ;SPOOLING FEATURE
;DEFINITIONS FOR SPOOLER COMMAND FILE:
CFORM←←0
RQNAM←←1
RQJOB←←2
FSIZE←←5
RQTIME←←6
FNAME←←7
AEXT←←14
CBITS←←16
;INITIALIZE SPOOLER IF ONE DOES NOT ALREADY EXIST
INTSPL: TRNE T1,2 ;SKIP IF NO JOBS LOGGED IN.
JRST MULSPL ;OOPS MORE THAN 1 SPOOLER ALREADY
MOVEI T1,SPRUNB ;ADDRESS OF RUN BLOCK
CALL T1,[SIXBIT/WAKEME/] ;LOGIN A PHANTOM JOB
JRST NOWAKE ;WAKE UUO FAILURE
MOVEI T2,30 ;WAIT MAX OF 24 SECONDS
INTSPS: MOVEI T1,1 ;SLEEP REGISTER
SLEEP T1, ;SLEEP A WHILE
MOVE T1,SPLNAM
CALL T1,[SIXBIT/NAMEIN/]
SOJGE T2,INTSPS ;WAIT SOME MORE.
JUMPL T2,SPLCFN
POPJ P, ;RETURN
SPRUNB:
SPLNAM: SIXBIT /[LIST]/
SPLPPN: SIXBIT /SPLSYS/ ;WHERE TO FIND IT
0 ;KEEP THIS JOB RUNNING
SPSUB: MOVE T1,SPLNAM ;FIND SPOOLER STATUS
CALL T1,[SIXBIT/NAMEIN/]
PUSHJ P,INTSPL ;HAVE TO INIT SPOOLER
MOVEM T1,SPOOLR ;T1 HAS JOB NUMBER OF SPOOLER
JBTSTS T1,
TLNE T1,20000 ;SKIP UNLESS ERROR STOP
TTCALL 3,[ASCIZ/
The spooler has crashed. Your output will be printed after
the spooler is restarted.
/]
INIT LPT,17 ;OPEN A CHANNEL
SIXBIT /DSK/
0
NERROR UNA
MOVE T1,OPENBK
HLLZ T2,OPENBK+1
SETZB T3,T4
LOOKUP LPT,T1 ;SEEK FILE
JRST SPLOKF ;LOOKUP FAILED
MOVS T4,T4
MOVM T4,T4 ;GET WD COUNT
LSH T4,-7 ;MAKE BLOCK COUNT
;OK. NOW, ALL I HAVE TO DO IS SETUP LPTBUF AND WRITE THE FILE
SETZM LPTBUF
MOVE T1,[XWD LPTBUF,LPTBUF+1]
BLT T1,LPTBUF+177
MOVE T1,['NP ',,1]
MOVEM T1,LPTBUF+CFORM
GETPPN T1,
MOVEM T1,LPTBUF+RQNAM ;SAVE REQUESTORS NAME
MOVEM T4,LPTBUF+FSIZE
DATE T1, ;GET DATE
HRLZM T1,LPTBUF+RQTIME ;SAVE
TIMER T1, ;TIME OF DAY
IDIVI T1,=3600 ;MAKE MINUTES
HRRM T1,LPTBUF+RQTIME ;SAVE
MOVE T1,[XWD OPENBK,LPTBUF+FNAME]
BLT T1,LPTBUF+FNAME+3 ;SAVE FILE NAME
HLLO T1,ORGEXT ;GET ORIGINAL EXTENSION
MOVEM T1,LPTBUF+AEXT ;SAVE AS ALIAS.
CALL T1,['PJOB '] ;GET JOB NUMBER
HRLZM T1,LPTBUF+RQJOB
SETO T1,
TTYUUO T1,6
HRRM T1,LPTBUF+RQJOB
MOVEI T1,1
MOVEM T1,LPTBUF+CBITS ;SET DELETE AFTER LISTING
MOVEI T1,0
CALL T1,['DSKPPN'] ;FIND OUT IF WE ARE SOMEWHERE ELSE.
MOVEM T1,LPTBUF+FNAME+3 ;SAVE THE PPN.
DATE T1,
TIMER T2,
LSH T1,=24
OR T1,T2
AGAIN: MOVSI T2,'SPX'
SETZ T3,
MOVE T4,SPLPPN
LOOKUP LPT,T1
JRST .+2
AOJA T1,AGAIN
MOVSI T2,'SPX'
SETZ T3,
MOVE T4,SPLPPN
ENTER LPT,T1
AOJA T1,AGAIN
OUTPUT LPT,[IOWD 200,LPTBUF
0]
STATZ LPT,740000
NERROR DDE
CLOSE LPT,
RELEAS LPT,
SETZM LPTBUF
MOVE T1,[XWD LPTBUF,LPTBUF+1]
BLT T1,LPTBUF+37
MOVE T1,SPOOLR
MOVEI T2,LPTBUF
SEND T1
JFCL
POPJ P,
> ;SPOOLING FEATURE.
SUBTTL SPOOLING ERRORS AND OTHER STUFF
SPLCFN: TTYUUO 3,[ASCIZ/
I just made a spooler, but now I can't find it.
/]
JRST COMND
MULSPL: TTYUUO 3,[ASCIZ/Spsub: There are multiple spoolers. Everyone loses
/]
JRST COMND
SPLOKF: TTYUUO 3,[ASCIZ/Spsub: Lookup failed on listing file.
/]
JRST COMND
NOWAKE: TTYUUO 3,[ASCIZ/Spsub: WAKEME to intiate spooler failed.
/]
JRST COMND
BEND LIST
SUBTTL JUSTIFICATION ROUTINES -- SRS
BEGIN JUST ;JUSTIFY TEXT AND OTHER GROOVY THINGS
↑JUST: SETZM LOLN ;AS USUAL
TRZ FL2,JFFLG!JRFLG!JLFLG!JCFLG!JPER ;CLEAR FLAGS
TRNE FL,READOF ;BETTER NOT BE READ ONLY
NERROR ILC ;SO TELL HIM
PUSHJ P,GNCH ;GET A CHARACTER
CAIE C,"r"
CAIN C,"R"
TRO FL2,JRFLG ;R FOR RIGHT
CAIE C,"l"
CAIN C,"L"
TRO FL2,JLFLG ;L FOR LEFT
CAIE C,"c"
CAIN C,"C"
TRO FL2,JCFLG ;C FOR CENTER
CAIE C,"u"
CAIN C,"U" ;U FOR JUSTIFY
TRO FL2,JFFLG ;WHICH IS THE ONLY THING WHICH FILLS
TRNN FL2,JRFLG!JLFLG!JCFLG!JFFLG
JRST JOIN ;MUST BE LINE NUMBER FOR JOIN
PUSHJ P,GET2S ;GET RANGE
CKTERM: TRNN FL,TERMF ;THIS HAD BETTER BE A TERMINATOR
NERROR ILC ;HE REALLY BLEW IT
MOVE T1,LOPG ;GET SET TO FIND LINE
MOVEM T1,DPG
MOVE SINDEX,LOLN
MOVEM SINDEX,LIBUF ;ALSO SET NEW FIRST LINE TO SAME
PUSHJ P,FIND ;FIND IT
PUSHJ P,INITOL ;SET IT UP
MOVEM T1,LIBUF ;SET NEW LINE NUMBER SAME AS OLD
PUSHJ P,INITNL ;AND SET UP THE NEW ONE
SETZM TPNT ;TELL JGET THERE IS NOTHING IN LIBUF2
MOVE T1,LMAR ;SET LEFT MARGIN
TRNE FL2,JFFLG ;IF FILLING
MOVE T1,PMAR ;MAKE THIS START OF PARAGRAPH
SOS T1
MOVEM T1,INDNT ;FOR INDENTATION
MOVEM T1,LINL ;AND LINE LENGTH
;THIS IS THE PART THAT GETS A CHARACTER FROM THE OLD LINE
JGET: SKIPN TPNT ;IS THERE ANY UNPROCESSED TAIL?
JRST JGET1 ;NO, GET A CHARACTER
MOVE T1,ELIN ;ARE WE AT END OF LINE?
CAMN T1,TPNT
JRST JGET2 ;YES, START GETTING FROM OLD LINE
ILDB T1,TPNT ;NO, GET A CHARACTER
JRST JPUT ;AND PUT.
JGET2: SETZM TPNT ;END OF TAIL
JGET1: ILDB T1,PNTR ;LOAD A CHARACTER
AOS OCNT1 ;STEP CHARACTER COUNT
CAIE T1,15 ;IS THIS A CR?
JRST JGET3 ;NO,TEST FOR END OF LINE
TRNN FL2,JFFLG ;ARE WE FILLING?
JRST JGET4 ;NO, WE'RE THROUGH
MOVEI T1," " ;YES, MAKE IT A BLANK
JRST JPUT ;AND GO PUT
JGET3: CAIE T1,12 ;END OF LINE?
JRST JPUT ;NOT YET, SO GO PUT
JGET4: ;END OF LINE
HRRZ T1,PNTR ;CURRENT WORD IN BUFFER FOR DELETION
SUB T1,OPTR ;- START OF OLD LINE
AOS T1 ;+1 = WORD COUNT OF OLD LINE
MOVEM T1,OCNT ;FOR INSED
TRNN FL2,JFFLG ;IF WE ARE NOT FILLING
JRST JGETE ;DO WHAT WE HAVE TO DO
SETZM NCNT ;OTHERWISE WE DELETE OLD LINE
MOVE PNTR,OPTR ;WHICH STARTS HERE
PUSHJ P,INSED ;USING INSED
PUSHJ P,FINDN1 ;MAKE SURE WE`RE AT START OF NEXT ONE
PUSHJ P,INITOL ;DO SETUP ON IT AND CHECK RANGE
JGETF: ILDB T1,PNTR ;GET FIRST CHARACTER
AOS OCNT1 ;STEP CHARACTER COUNT
CAIE T1,11 ;IS IT A TAB
CAIN T1,15 ;OR CR?
JRST PARA ;YES, START A NEW PARAGRAPH
JRST JPUT ;NO, GO PUT
JGETE: MOVE T1,LINL ;LINE LENGTH
MOVEM T1,WRDL ;TO WRDL BECAUSE CR AS BLANK WAS DELETED
MOVEM ALTP,LWRD ;ALSO STORE POINTER TO END OF LINE
CAMLE T1,MAXL ;IF LINE WAS TOO LONG,
RERROR LTL ;TELL HIM SO
PUSHJ P,JSUB ;CLEAN UP NEW LINE AND PUT IT OUT
PUSHJ P,INITOL ;SET UP NEXT LINE
MOVEM T1,LIBUF ;SET NEW LINE NUMBER SAME AS OLD
SETZM TPNT ;NOTHING IN LIBUF2
JRST JGET2 ;START MUNCHING
;THIS IS THE PART THAT PUTS A CHARACTER INTO THE NEW LINE
JPUT: CAIE T1," " ;IS THIS A BLANK?
JRST JPUTN ;NO, CHECK SOME OTHER STUFF
TRNE FL2,JPER ;IF WE HAVE SEEN A PERIOD OR SOMETHING
TRNN FL2,JBLF ;AND THIS IS NOT THE FIRST BLANK
SKIPA
JRST JPUTN1 ;PERMIT IT ANYWAY BUT DON'T TELL ANYONE
TROE FL2,JBLF ;WAS THERE ONE BEFORE IT?
JRST JGET ;YES; WE DON`T WANT IT
TRNN FL2,JFFLG ;ARE WE FILLING?
TRZ FL2,JBLF ;NO, PERMIT AN EXTRA BLANK
AOS WCNT ;STEP WORDCOUNT
MOVE T2,LINL ;GET LENGTH SO FAR
MOVEM T2,WRDL ;AND SAVE IT FOR JSUB
MOVEM ALTP,LWRD ;AND STORE POINTER TO END OF WORD
JRST JPUT1 ;THEN PUT BLANKIN BUFFER
JPUTN: TRZ FL2,JBLF!JPER ;NOT A BLANK
CAIN T1,"." ;IS IT A PERIOD
TRO FL2,JPER
CAIN T1,":" ;OR COLON
TRO FL2,JPER
CAIN T1,"?" ;OR QUESTION MARK
TRO FL2,JPER
CAIN T1,"!" ;OR EXCLAMATION?
TRO FL2,JPER ;IF SO PERMIT EXTRA BLANKS
JPUTN1: MOVE T2,LINL ;LENGTH SO FAR
JPUT1: IDPB T1,ALTP ;DEPOSIT CHARACTER
ADD T2,WTBL@ ;WIDTH OF CHARACTER
CAIE T1,11 ;WAS THAT A TAB?
JRST JPUT2 ;NO
TRZE T2,7 ;YES. IF LAST 3 BITS ARE NONZERO
ADDI T2,10 ;WE WERN'T AT TAB POSITION
SETZM WCNT ;RESET WORDCOUNT
SETZM LWRD ;LAST WORD LOCATION
MOVEM ALTP,BLIN ;AND LOGICAL BEGINNING OF LINE FOR JSUB
TRNE FL2,JFFLG ;IF FILLING
TRO FL2,JBLF ;DELETE A FOLLOWING BLANK
JPUT2: MOVEM T2,LINL ;STORE NEW LENGTH
CAMLE T2,MAXL ;ARE WE OVER THE END?
JRST JPUTEL ;YES, END LINE WE ARE NOW ON
CAME ALTP,[POINT 7,LIBUF2+MXWPL,34] ;NO, HAVE WE FILLED BUFFER?
JRST JGET ;NOT YET, GET ANOTHER
JPUTEL: SKIPE LWRD ;ANY WORDS YET?
JRST JPUTE ;YES, PUT OUT LINE
RERROR LTL ;NO, TELL HIM LINE TOO LONG
MOVE T2,MAXL ;SAY LINE IS LONG ENOUGH
MOVEM T2,WRDL
JPUTE: TRNE FL2,JFFLG ;UNLESS WE'RE NOT FILLING (IN WHICH CASE THIS IS A MISTAKE)
PUSHJ P,JSUB ;MOVE OUT A NEW LINE, AFTER JUSTIFYING IT
JRST JGET ;THEN GET ANOTHER CHARACTER
;THIS PUTS OUT A NEW LINE
NLOUT: MOVEI T1,15 ;ADD A CR
IDPB T1,ALTP
MOVEI T1,12 ;AND A LF
IDPB T1,ALTP
HRRZ T1,ALTP ;LAST WORD OF LINE
SUBI T1,LIBUF ;-FIRST
AOS T1 ;+1=WORDCOUNT
MOVEM T1,NCNT ;FOR INSERTION INTO BUFFER
TRNE FL2,JFFLG ;IF FILLING
SETZM OCNT ;INSERT BEFORE
MOVE PNTR,OPTR ;ELSE REPLACE, THE OLD LINE
PUSHJ P,INSED ;DONE BY INSED
PUSHJ P,FINDN ;FIND OLD LINE
PUSHJ P,FILLB ;AND KEEP FROM LOSING IT
TRNN FL2,JFFLG ;IF NOT FILLING
JRST INITNL ;SET UP NEW LINE ON THE WAY BACK
MOVE T2,INCR ;INCR FOR LINE NUMBERS
MOVE T1,LIBUF ;OLD LINE NUMBER
PUSHJ P,ASCIAD ;ADD TO MAKE NEW ONE
MOVEM T1,LIBUF ;AND STORE IT AWAY
CAMG T1,MAXLN ;TOO HIGH?
JRST NLO2 ;NO, EXIT
AOS T1,CPG ;YES, WILL SOON BE ON NEXT PAGE
MOVEM T1,CPGL ;AND LOGICAL PAGE
AOS BGPG ;ADD ONE MORE PAGE
AOS INPG
AOS HIPG
MOVE T1,PGMK ;INSERT PAGEMARK
MOVEM T1,LIBUF ;IN LINE BUFFER
MOVE T1,[BYTE (7) 15,15,14] ;AND TEXT THEREOF
MOVEM T1,LIBUF+1
SETZM OCNT ;INSERT
MOVEI T1,2 ;2 WORDS
MOVEM T1,NCNT
PUSHJ P,INSED ;INTO TEXT FILE
MOVE T2,INCR ;INCR AGAIN
MOVEM T2,LIBUF ;TO MAKE FIRST LINE NUMBER
PUSHJ P,FINDN ;MOVE PAST IT
PUSHJ P,FILLB ;FILL BUFFER TO KEEP FROM LOSING IT
MSG (T1,PAGE MARK INSERTED)
NLO2: MOVE T1,OCNT1 ;CHARACTERS PROCESSED SO FAR
MOVEM PNTR,OPTR ;REMEMBER WHERE WE ARE
AOS PNTR ;SKIP LINE NUMBER
HRLI PNTR,(<POINT 7,0>) ;MAKE BYTE POINTER
NLO1: IBP PNTR ;TO MOVE PNTR BACK
SOJGE T1,NLO1 ;TO WHERE WE FOUND IT
JRST INITNL ;THEN SET UP NEW LINE ON WAY BACK
;THIS SETS UP A NEW OLD LINE FOR GET
INITOL: PUSHJ P,FINDN1 ;MAKE SURE WE ARE AT START OF LINE
INITO1: HRRZM PNTR,OPTR ;SAVE POINTER TO START OF LINE
PUSHJ P,ONMOV ;CHECK RANGE
JRST JSTEND ;FINISHED
CAMN T1,PGMK ;IS IT A PAGEMARK?
JRST INITOP ;YES
MOVEM T1,CLN ;NO, SET CURRENT LINE
MOVE T2,CPG ;AND PAGE
MOVEM T2,CPGL
SETZM OCNT1 ;NO CHARACTERS YET
SETZM TCHR ;NOT KNOWN TO BE START OF PARAGRAPH
AOS PNTR ;SKIP LINE NUMBER
HRLI PNTR,(<POINT 7,0>) ;MAKE BYTE POINTER
IBP PNTR ;SKIP INITIAL TAB
POPJ P, ;EXIT
INITOP: ;FOUND A PAGEMARK
TRNE FL2,JFFLG ;ARE WE FILLING?
JRST INITOD ;YES, DELETE IT
AOS T2,CPG ;NO, WE ARE ON NEW PAGE
MOVEM T2,CPGL
PUSHJ P,FINDN ;FIND NEXT LINE
PUSHJ P,FILLB ;HANG ON TO IT
JRST INITO1 ;AND SEE WHAT'S THERE
INITOD: SETZM NCNT ;DELETE PAGEMARK
MOVEI T1,2 ;2 WORDS LONG
MOVEM T1,OCNT
PUSHJ P,INSED ;USE INSED AS USUAL
SOS BGPG ;NOW HAVE ONE LESS PAGE
SOS INPG
SOS HIPG
JRST INITOL ;LOOK AT NEXT LINE
INITNL: SETZM LIBUF+1 ;CODE TO ZERO THE LINE BUFFER
MOVE T1,[XWD LIBUF+1,LIBUF+2]
BLT T1,LIBUF+MXWPL+1
MOVE ALTP,[POINT 7,LIBUF2] ;POINT ALTP AT START OF LIBUF2
MOVEI T1,11 ;TAB TO START LINE
IDPB T1,ALTP ;SO INSERT IT
MOVEM ALTP,BLIN ;AND SAVE LOGICAL BEGINNING OF LINE
TRO FL2,JBLF ; KEEP FROM INSERTING LEADING BLANKS
TRZ FL2,JPER
MOVE T1,LMAR ;SET LEFT MARGIN
SOS T1 ;MARGIN -1 = EXTRA BLANKS
MOVEM T1,LINL ;FOR EXTRA LINE LENGTH
MOVEM T1,INDNT ;AND INDENTATION
SETZB T1,WCNT ;AND THERE ARE NO WORDS YET
SETZM WRDL ;NOR CHARACTERS, FOR THAT MATTER
EXCH T1,LWRD ;RESET POINTER TO LAST WORD
MOVEM T1,TPNT ;BUT SAVE IT TO GET TAIL
POPJ P, ;RETURN
;THIS STARTS A NEW PARAGRAPH
PARA: MOVEM T1,TCHR ;STORE TERMINATING CHARACTER
SKIPE LWRD ;ANY WORDS YET?
PUSHJ P,JSUB ;YES, GET RID OF OLD LINE
MOVE T1,TCHR ;GET TERMINATOR BACK
SETZM TCHR ;DON'T CONFUSE PEOPLE
SETZM TPNT ;TELL JGET NOTHING REMAINS IN LIBUF2
SETZM INDNT ;IF TAB, NO SPECIAL INDENTATION
SETZM LINL
CAIN T1,11 ;IS IT A TAB?
JRST JPUT ;YES, PUT IT IN NEW LINE
PUSHJ P,JSUB ;MUST HAVE BEEN BLANK LINE
MOVE T1,PMAR ;SET PARAGRAPH MARGIN
SOS T1
MOVEM T1,INDNT
MOVEM T1,LINL
JRST JGET ;SO GET NEW CHARACTER
;THIS FINISHES EVERYTHING UP
JSTEND: SETOM TCHR ;FAKE END OF PARAGRAPH
SKIPE LWRD ;ANYTHING LEFT?
PUSHJ P,JSUB ;YES, GET RID OF IT
MOVE PNTR,OPTR ;GET BACK OLD POINTER
MOVE T1,(PNTR) ;GET LINE NUMBER
MOVEM T1,LIBUF ;SAVE NUMBER OF NEXT LINE
PUSHJ P,FINDB ;GET LINE LAST FILLED
MOVEM T1,CLN ;SET IT AS CURRENT LINE
EXCH T1,LIBUF
SKIPE T1 ;END OF FILE?
CAMN T1,PGMK ;PAGE MARK NEXT?
JRST COMND ;DON'T WORRY ABOUT ORDER
CAMG T1,LIBUF ;ORDER TROUBLE?
NERROR ORDER ;YES
JRST COMND ;NO, WE'RE THROUGH.
;AT LAST! THE JUSTIFICATION OF ALL THIS STUFF!
JSUB: MOVEM ALTP,ELIN ;SAVE END OF LINE FOR GET
MOVE ALTP,[POINT 7,LIBUF+1] ;WHERE TO DEPOSIT
MOVE T4,[POINT 7,LIBUF2] ;WHERE TO LOAD
MOVNS JFLOP ;PUT BLANKS IN OTHER SIDE THIS TIME
JSUB1: ILDB T1,T4 ;GET A CHARACTER
IDPB T1,ALTP ;AND MOVE IT
CAME T4,BLIN ;WAS THAT THE LAST TAB?
JRST JSUB1 ;NO, MOVE ANOTHER
SKIPN T5,LWRD ;IF NO WORDS THERE
MOVE T5,ELIN ;THIS IS WHERE TO STOP
SKIPN WRDL ;IF NOTHING IS THERE AT ALL
JRST NLOUT ;PUT OUT BLANK LINE
;NOW WE COMPUTE NUMBER OF BLANKS TO INSERT, IF ANY
SETZM T2
SETZM BPW
SETZM REM
TRNE FL2,JLFLG ;IF LEFT JUSTIFYING,
JRST JSUBM1 ;WE DON'T WANT ANY
MOVEI T1," "
MOVE T2,MAXL ;DESIRED LENGTH
SUB T2,WRDL ;-LENGTH WE HAVE = WHAT WE WANT
JUMPE T2,JSUBM1 ;IF ZERO, GO MOVE REST OF LINE
IDIV T2,@WTBL ;/WIDTH OF BLANK = BLANKS WE NEED
TRNE FL2,JCFLG ;IF CENTERING
ASH T2,-1 ;WE ONLY WANT HALF AS MANY
TRNE FL2,JRFLG!JCFLG ;IF NOT JUSTIFYING BOTH MARGINS
JRST JSUBM1 ;GO PUT IN SOME BLANKS
SOSLE WCNT ;IF LESS THAN 2 WORDS
SKIPE TCHR ;OR END OF PARAGRAPH
JRST JSUBM ;DON'T BOTHER
IDIV T2,WCNT ;BLANKS/WORDS
MOVEM T2,BPW ;= BLANKS PER WORD
MOVEM T3,REM ;AND REMAINDER
SKIPL JFLOP
JRST JSUBM
AOS BPW ;EVERY OTHER LINE
SUB T3,WCNT ;WE ADD EXTRA BLANKS
MOVNM T3,REM ;ON THE OTHER SIDE
JSUBM: SETZM T2
;MOVE LINE, INSERTING BLANKS
JSUBM1: ADD T2,INDNT ;DO INDENTATION
JSUBM3: SOJL T2,JSUBM2 ;QUIT IF NONE
IDPB T1,ALTP ;ELSE DEPOSIT
SOJGE T2,.-1 ;AND TRY AGAIN
JSUBM2: CAMN T4,T5 ;WAS IT THE LAST?
JRST NLOUT ;YES, PUT OUT NEW LINE
ILDB T1,T4 ;GET ANOTHER CHARACTER
IDPB T1,ALTP ;DEPOSIT IT
SKIPN TCHR ;AT END OF PARAGRAPH WE DO NOT LOOK FOR BANKS
TRNN FL2,JFFLG ;ARE WE LOOKING FOR BLANKS?
JRST JSUBM2 ;NO, MOVE ANOTHER
JSUBB: CAIE T1," " ;YES, IS IT A BLANK?
JRST JSUBBN ;NO
TROE FL2,JBLF ;YES, DID WE JUST SEE ONE?
JRST JSUBM2 ;YES, MOVE ANOTHER
MOVE T2,BPW ;NO, GET BLANKS PER WORD
SOSL REM ;IF REMAINDER STILL > 0
ADD T2,JFLOP ;ADD ANOTHER ON ALTERNATE LINES
JRST JSUBM3 ;AND PUT THEM IN
JSUBBN: TRZ FL2,JBLF ;NOT A BLANK
JRST JSUBM2 ;GET ANOTHER
BEND JUST
SUBTTL "←" SET PARAMETERS ROUTINE
BEGIN SET
↑SET: PUSHJ P,SCAN ;GET THE THING TO SET TO
TRNN FL,IDF ;MUST BE AN IDENT
NERROR ILC
PUSH P,ACCUM ;SAVE IT
PUSHJ P,SCAN ;AND CHECK FOR TERMINATOR
CAIN C,"=" ;IS IT AN =?
JRST SETVAR ;YES, SET SOME VARIABLE
TRNN FL,TERMF ;NO, SHOULD BE TERMINATOR
NERROR ILC
POP P,T1 ;SHOULD BE "UPPER" OR "LOWER"
MOVNI T2,1 ;CHECK
CAMN T1,[SIXBIT /UPPER/]
MOVEI T2,0 ;USE 0 FOR UPPER CASE
CAMN T1,[SIXBIT /LOWER/]
MOVEI T2,40 ;AND 40 FOR LOWER
SKIPGE T2 ;DID WE SET ONE OR THE OTHER
JRST SET1 ;TEY FOR MODEL NUMBER
MOVEM T2,CASEBT ;SET UP CASE
JRST COMND
SET1: CAMN T1,[SIXBIT /M37/] ;MODEL 37?
JRST SETM37
CAMN T1,[SIXBIT /DPY/]
JRST SETDPY
CAMN T1,[SIXBIT /NOVICE/]
JRST SETNOV
CAMN T1,[SIXBIT /EXPERT/]
JRST SETEXP
CAMN T1,[SIXBIT /C128/]
JRST QON
CAMN T1,[SIXBIT /C64/]
JRST QOFF
CAME T1,[SIXBIT /M33/] ;OR 33
NERROR ILC ;LOSE
TRZA FL,M37F ;MODEL 33
SETM37: TRO FL,M37F
TRZ FL,DPYF ;IN NEITHER CASE IS IT A DISPLAY
JRST COMND
SETDPY: TRZ FL,M37F ;NOT A MODEL 37
TRO FL,DPYF ;BUT IS A DISPLAY
JRST COMND
QON: TLZA FL,QMODF
QOFF: TLO FL,QMODF
JRST COMND
SETNOV: TRZA FL,EXTOG
SETEXP: TRO FL,EXTOG
JRST COMND
SETVAR: PUSHJ P,SCAN ;GET A NUMBER
TRNN FL,NUMF ;IT HAD BETTER BE ONE
NERROR ILC
PUSH P,T2 ;SAVE IT
PUSH P,T1 ;IN BINARY AND ASCII
PUSHJ P,SCAN ;CHECK FOR TERMINATOR
TRNN FL,TERMF ;WHICH HAD BETTER BE THERE
NERROR ILC
POP P,T1 ;GET BACK ASCID
POP P,T2 ;BINARY
POP P,T3 ;AND THE IDENTIFIER
CAME T3,[SIXBIT /RMAR/]
JRST SETV2
MOVEM T2,RMAR ;RIGHT MARGIN FOR JUSTIFY
JRST COMND
SETV2: CAME T3,[SIXBIT /MAXLN/]
JRST SETV3
MOVEM T1,MAXLN ;MAXIMUM LINE NUMBER
JRST COMND
SETV3: CAME T3,[SIXBIT /INC/]
JRST SETV4
MOVEM T1,INCR ;LINE NUMBER INCREMENT FOR EVERYONE
JRST COMND
SETV4: CAME T3,[SIXBIT /LMAR/]
JRST SETV5
MOVEM T2,LMAR ;LEFT MARGIN FOR JUSTIFY
JRST COMND
SETV5: CAME T3,[SIXBIT /PMAR/]
JRST SETV6
MOVEM T2,PMAR ;PARAGRAPH STARTING POINT
JRST COMND
SETV6: CAME T3,[SIXBIT /SAVE/]
JRST SETV7
MOVEM T2,SAVNUM ;# OPERATIONS BETWEEN SUGGESTED "W"'S
MOVEM T2,SAVCNT ;INITIALIZE COUNTER TO THAT VALUE TOO
JRST COMND
SETV7: CAME T3,[SIXBIT /ISAVE/]
NERROR ILC
ADDI T2,1
MOVEM T2,ISVNUM ;INSERT MODE AUTO SAVE
MOVEM T2,ISVCNT
JRST COMND
BEND SET
SUBTTL "=" GIVE PARAMETERS ROUTINE
BEGIN GIVE
↑GIVE: PUSHJ P,SCAN ;FIND OUT WHAT HE WANTS TO KNOW
CAIN C,"." ;CURRENT LINE/PAGE?
JRST GVDOT ;YES
TRNN FL,IDF ;IF NOT, MUST BE AN IDENT
NERROR ILC
PUSH P,ACCUM ;SAVE IT
PUSHJ P,SCAN ;CHECK FOR TERM
TRNN FL,TERMF
NERROR ILC
POP P,T1 ;NOW FIND OUT WHAT HE WANTS
CAMN T1,[SIXBIT /ERROR/]
JRST GIVER
CAMN T1,[SIXBIT /CASE/]
JRST GVCASE
CAMN T1,[SIXBIT /STRING/] ;DOES HE WANT STRINGS?
JRST GVSTR
CAMN T1,[SIXBIT /INC/]
JRST GVINC ;CURRENT INCREMENT
CAMN T1,[SIXBIT /RMAR/]
JRST GVRM ;RIGHT MARGIN
CAMN T1,[SIXBIT /MAXLN/]
JRST GVMLN ;MAXIMUM LINE NUMBER
CAMN T1,[SIXBIT /LMAR/]
JRST GVLM ;LEFT MARGIN
CAMN T1,[SIXBIT /PMAR/]
JRST GVPM ;PARAGRAPH MARGIN
CAMN T1,[SIXBIT /SAVE/]
JRST GVSV ;# OPS BETWEEN SUGGESTED "W"'S
CAMN T1,[SIXBIT /ISAVE/]
JRST GVISV ;#OPS BETWEEN "W"'S IN INSERT MODE
CAMN T1,[SIXBIT /FILE/]
JRST GVFLNM ;TELL USER WHAT FILE HE'S EDITING
CAME T1,[SIXBIT /BIG/]
NERROR ILC ;NOTHING
TRNE FL,BGSN ;HAVE WE SEEN THAT PAGE
JRST GVBG1 ;YES, ALL IS OK
MOVSI T1,1 ;WILL HAVE TO SEARCH FOR IT
MOVEM T1,DPG
MOVEI SINDEX,0
PUSHJ P,FIND
TRNN FL,BGSN ;SHOULD HAVE SEEN IT NOW
ERROR ICN ;WE ARE IN TROUBLE
GVBG1: MOVE T1,BGPG ;GET IT
GIV2: MOVEI T3,OCHR ;ROUTINE FOR DECIMAL PRINTER TO OUTPUT TO
PUSHJ P,DECPR ;PRINT DECIMAL
OUTPUT TTY,0 ;FORCE OUTPUT
GIV1: TERPRI (T1)
JRST COMND
GVCASE: IFE FULDPX,<MOVEI T1,[ASCIZ /MODEL 37 /] ;TELL HIM HE'S A 37
TRNE FL,DPYF ;IF A DPY
MOVEI T1,[ASCIZ /DISPLAY /]
TRNE FL,M37F!DPYF ;BUT ONLY IF HE IS
CALLI T1,3
MOVEI T1,[ASCIZ /C64 /]
TLNE FL,QMODF
CALLI T1,3>
IFN FULDPX,<TRNE FL,DPYF
TTYUUO 3,[ASCIZ /DISPLAY /]
TRNE FL,M37F
TTYUUO 3,[ASCIZ /MODEL 37 /]
TLNE FL,QMODF
TTYUUO 3,[ASCIZ /C64 /]>
MOVEI T1,[ASCIZ /LOWER
/]
SKIPN CASEBT
MOVEI T1,[ASCIZ /UPPER
/]
CALLI T1,3 ;PRINT CURRENT CASE
JRST COMND
GIVER: SKIPN T1,SVERN
JRST COMND
IFE FULDPX,<MOVE T1,ETBL2-1(T1)
CALLI T1,3>
IFN FULDPX,<TTYUUO 3,@ETBL2-1(T1)>
JRST COMND
GVISV: MOVE T1,ISVNUM ;OPS BETWEEN "W"'S, INSERT MODE
JRST GIV2
GVSV: SKIPA T1,SAVNUM ;OPS BETWEEN "W"'S
GVRM: MOVE T1,RMAR ;RIGHT MARGIN
JRST GIV2
GVINC: SKIPA T1,INCR ;GET CURRENT INCREMENT
GVMLN: MOVE T1,MAXLN ;MAXIMUM LINE NUMBER
PUSHJ P,OUTSN
JRST GIV1
GVLM: SKIPA T1,LMAR ;LEFT MARGIN
GVPM: MOVE T1,PMAR ;PARAGRAPH LEFT MARGIN
JRST GIV2
GVDOT: PUSHJ P,SCAN ;SEE IF A TERMINATOR IS THERE
TRNN FL,TERMF
NERROR ILC ;NO TERMINATOR
MOVE T1,CLN ;GET CURRENT LINE
MOVEM T1,LINOUT
IFE FULDPX,<MOVEI T1,LINOUT ;NOW PRINT IT (FOLLOWED BY /)
CALLI T1,3>
IFN FULDPX,<TTYUUO 3,LINOUT>
MOVE T1,CPGL ;AND CURRENT PAGE
JRST GIV2 ;|O TO IT
GVSTR: MOVEI T1,SRPNT ;GET THE POINTER TO POINTER BLOCK
HRLI T1,-SRNUM ;SET COUNT
MSG (C, SEARCH:)
PUSHJ P,GVSTR3
MOVEI T1,R2PNT
HRLI T1,-SRNUM
MSG (C, SUBSTITUTE:)
PUSHJ P,GVSTR3
MOVEI T1,R1PNT
HRLI T1,-SRNUM
MSG (C,< FOR:>)
PUSHJ P,GVSTR3
JRST COMND
GVSTR3: SKIPN T2,(T1) ;IS THERE ONE THERE?
POPJ P, ;NO, DONE
GVSTR2: ILDB C,T2 ;NEXT CHR
JUMPE C,GVSTR1 ;DONE
PUSHJ P,OCHR ;PRINT IT
JRST GVSTR2 ;AND CONTINUE
GVSTR1: OUTPUT TTY,0 ;CLEAR OUTPUT DEVICE
TERPRI (T2)
AOBJN T1,GVSTR3 ;IF THERE IS ONE
POPJ P,
; GIVE USER FILE NAME
GVFLNM: MOVE T2,ORGNAM ;FILE NAME
PUSHJ P,SIXPRT ;PRINT IT
SKIPN T2,ORGEXT ;IS THERE AN EXTENSION?
JRST CHKPPN ; NO, CHECK PROJ/PROG
OUTSTR [ASCII /./] ;EXTENSION DELIM
PUSHJ P,SIXPRT ;EXTENSION NAME
; `W' CODE PUTS ORIGINAL EXT IN ORGPPN FOR SOME REASON --
; CHECK FOR IT BY TESTING RH
CHKPPN: SKIPE T2,ORGPPN ;PPN IN EDIT?
TRNN T2,-1 ;MAKE SURE REALLY A PPN
JRST CHKRON ;NO, CHECK READ-ONLY
OUTSTR [ASCII /[/]
HLLZS T2
PUSHJ P,SIXLJP ;LEFT-JUSTIFY, THEN PRINT
OUTSTR [ASCII /,/]
HRLZ T2,ORGPPN
PUSHJ P,SIXLJP
OUTSTR [ASCII /]/] ;FINISH UP
CHKRON: TRNE FL,READOF ;READ-ONLY?
OUTSTR [ASCII ./R.] ;YES
JRST GIV1 ;DONE
BEND GIVE
SUBTTL COMMON ROUTINES FOR SEARCH AND SUBSTITUTE ROUTINES
COMMENT ! SOME COMMON ROUTINES FOR SEARCHING FILES!
COMMENT ! THIS ROUTINE GENERATES CODE FOR FINDING A MATCH
FOR THE FIRST CHARACTER OF A SEARCH STRING. THE POINTER
TO A SET OF BYTE POINTERS FOR SEARCH STRINGS IS IN T1 !
BEGIN CODSR
UGGHH: TLC FL,NEGF
TLO FL,DEMCHR ;WE REALLY JEED IT
JRST READCH
↑CODSR: MOVEI T2,CODEBF ;SET UP POINTER TO PLACETO PUT CODE
MOVEI ALTP,0 ;THE NUMBER OF THE CURRENT STRING
HRLI T1,-SRNUM ;THE NUMBER OF STRINGS
CODS5: TLZ FL,NEGF!DEMCHR ;TURN OFF THE ¬ SEEN FLAG
MOVE T3,(T1) ;GET A POINTER
JUMPE T3,ENDCOD ;A ZERO BYTE POINTER IS END OF CODE
READCH: ILDB C,T3 ;PICK UP A CHARACTER IN STRING
JUMPE C,[TLNE FL,DEMCHR ;DID WE REALLY WANT ONE
NERROR ISS ;YES, LOSE
SUBI T2,2 ;NO, ALWAYS MATCH
JRST COMXCT]
CAIN C,"∞" ;ARBITRARY NUMBER OF SOMETHING
JRST ARBIT
CAIN C,"∀" ;ANY CHARACTER
JRST ANY
CAIN C,"¬" ;NOT THIS ONE
JRST UGGHH
CAIN C,"|" ;SEPARATOR
JRST SEP
CAIN C,"≡" ;QUOTE THE NEXT CHARACTER
JRST QUOTE
COMLET: MOVE CS,CTBL(C) ;GET THE MAJIC BITS
TLNN FL,EXCTS1!EXCTSR ;IS THIS AN EXACT SEARCH?
TLNN CS,LETF⊗16 ;OR NOT A LETTER
JRST NORMCR ;YES JUST THE TEST
HRLI C,(<CAIE C,>) ;DO A CAIE
MOVEM C,(T2)
XOR C,[<CAIN 40>≠<CAIE>] ;AND TEST FOR OTHER CASE
MOVEM C,1(T2)
TLNE FL,NEGF ;¬ THAT CHR
JRST GENSKP ;GENERATE A SKIPA
COMXCT: MOVE C,[XCT JSPR] ;THE CALL TO SEARCH FURTHER
DPB ALTP,[POINT 4,C,12] ;AC FIELD GIVES STRING NUMBER
MOVEM C,2(T2)
ADDI T2,3 ;ADVANCE OUTPUT POINTER
ENDSTR: ADDI ALTP,1 ;NEXT STRING
AOBJN T1,CODS5 ;IF ANY
ENDCOD: MOVE C,[JRST COMSRT] ;A RETURN
MOVEM C,(T2)
POPJ P,
SEP: MOVE C,[SKIPG CS,CTBL(C)] ;GET BITS
MOVEM C,(T2)
MOVE C,[TRNE CS,NSEPF] ;CHECK FOR %,$,OR .
MOVEM C,1(T2)
TLNE FL,NEGF ;SKIPA IN NORMAL CASE
JRST COMXCT
GENSKP: MOVSI C,(<SKIPA>)
MOVEM C,2(T2)
AOJA T2,COMXCT ;SO XCT WILL GO IN RIGHT PLACE
QUOTE: ILDB C,T3 ;GET NEXT CHR
JUMPE C,[NERROR ISS] ;END OF STRING IS ILLEGAL
JRST COMLET ;TREAT AS NORMAL CHARACTER
NORMCR: HRLI C,(<CAIN C,>) ;EXACT OR NOT LETTER
TLNE FL,NEGF
TLC C,(<CAIN>≠<CAIE>) ;USE OTHER TEST
NORMC1: MOVEM C,(T2)
SOJA T2,COMXCT ;MAKE THE XCT GO IN RIGHT PL@CE
ANY: MOVE C,[CAIE C,15] ;¬∀ IS 15
TLNE FL,NEGF
TLC C,(<CAIN>≠<CAIE>)
JRST NORMC1
ARBIT: ILDB C,T3 ;GET NEXT
CAIN C,"¬" ;JUST CHECK VALIDITY
JRST ARBIT
CAIN C,"≡"
ILDB C,T3
JUMPE C,[NERROR ISS] ;END OF STRING ERROR
JRST READCH ;LOOK FOR FIRST OTHER CHR
JSPR: JSP T1,SRCRET ;CALL CONTINUE SEARCH
BEND CODSR
;READ INTHE STRING TO SEARCH FOR
;T3 HAS PLACE TO PUT POINTERS T1 A BYTE POINTER FOR STRINGS
BEGIN SSTRNG
↑SSTRNG:MOVEI T2,SRBLG ;THE PERMISSIBLE LENGTH
HRLI T3,-SRNUM ;T3 HAS POINTER TO PLACE BYTE POINTERS
SSTR0: MOVEM T1,SVPT ;SAVE THE POINTER FOR END OF STRING
SSTR1: PUSHJ P,GNCH ;GET A CHR
CAIN C,200 ;ALTMODE TERMINATES
JRST SSTEND
CAIN C,15 ;IGNORE RETURNS
JRST SSTR1
CAIN C,12 ;LINE FEED IS END OF ONE STRING
JRST SSTR2
IDPB C,T1 ;PUT IN OUTPUT STRING
SOJG T2,SSTR1
SSTR3: RERROR STL ;THE STRING WAS TOO LONG
SSTR4: HRLZ T1,T3 ;ZERO OUT FIRST POINTER
MOVNS T1
ADDI T1,-SRNUM(T3) ;FIND START
SETZM (T1)
JRST COMND
SSTR2: CAMN T1,SVPT ;NULL STRING?
JRST [HLRZ C,T3 ;FIRST ONE?
CAIE C,-SRNUM ;WELL?
JRST .+1 ;NO
MOVEI C,12 ;RETURN A LINE FEED
POPJ P,]
↑RETSTR:MOVEI C,0 ;TERMINATE STRING WITH 0
IDPB C,T1
SOJLE T2,SSTR3
MOVE C,SVPT ;SET UP POINTER
MOVEM C,(T3)
AOBJN T3,SSTR0 ;IF ROOM FOR MORE, GET THEM
RERROR TMS ;TOO MANY GIVEN
JRST SSTR4
SSTEND: CAIN T2,SRBLG ;DID WE SEE ANY?
POPJ P, ;NO, RETURN
MOVEI C,0 ;YES, TERMINATE LAST
IDPB C,T1
MOVE T1,SVPT
MOVEM T1,(T3) ;SET POINTER
SSTR5: AOBJP T3,CPOPJ1 ;ZERO OUT OTHER POINTERS
SETZM (T3)
JRST SSTR5
BEND SSTRNG
;THE SEARCH ITSELF
BEGIN COMSRC
↑COMSRC:MOVEM T2,BUFSAV ;SAVE THE POINTER TO STRINGS
MOVNI T3,1 ;THE COUNT OF HOW FAR INTO LINE WE ARE
MOVEI ALTP,1(PNTR) ;SET BYTE POINTER
HRLI ALTP,(<POINT 7,0,6>)
MOVEI C,15 ;START WITH A LINE DELIMITER
JRST CODEBF ;GO SCAN
↑COMSRT:ILDB C,ALTP ;WE RETURN HERE IF NO MATCH FOR THIS ONE
CAIE C,15 ;DONE?
AOJA T3,CODEBF ;NO, GO ON
POPJ P, ;YES, NON-MATCH RETUNR
↑SRCRET:PUSH P,T1 ;SAVE THE RETURN ADDRESS
PUSH P,ALTP ;AND THE STRING POINTER
PUSH P,C ;AND THE CHARACTER
LDB T1,[POINT 4,-1(T1),12] ;GET STRING NUMBER
ADD T1,BUFSAV ;POINT TO BYTE POINTER
SKIPN T1,(T1) ;GET IT
ERROR ICN ;THERE SHOULD BE ONE THERE
MOVE T2,[POINT 7,ARBBUF] ;SET UP ARBIT MATCH
MOVEI T4,MXWPL*=10 ;POINTER AND COUNT
SETZM ARBCNT ;THE NUMBER OF ARBITRARY MATCHES SEEN
TLZ FL,ARBITG ;OFF AT START
PUSHJ P,LINMAT ;GO CHECK FOR MATCH
JRST LOSE ;WE LOSE, CONTINUE SCAN
MOVEM ALTP,SRCALP ;POINTER TO END OF STRING
POP P,C ;RESTORE
POP P,ALTP
POP P,T1
↑CPOPJ1:AOS (P) ;SKIP RETURN
POPJ P,
LOSE: POP P,C ;RESTORE
POP P,ALTP
POPJ P, ;AND CONTINUE SEARCH
NXTCHR: CAIN C,12 ;WAS THAT LAST OF LINE?
POPJ P, ;YES, LOSE
ILDB C,ALTP ;NO, TRY NEXT
LINMAT: PUSHJ P,CHRMAT ;CHECK FOR MATCH
POPJ P, ;NONE, RETURN
CAIE CS,0 ;IS SO ALL DONE
JRST NXTCHR ;NO, TRY MORE
JRST CPOPJ1 ;SKIP RETURN
BEGIN CHRMAT
↑CHRMAT:TLZ FL,NEGF!DEMCHR ;NO ¬ SEEN AND CHR CAN BE 0
READCH: ILDB CS,T1 ;GET NEXT
JUMPE CS,MATCH ;END OF STRING IS USUALLY GOOD
CAIN CS,"¬" ;CHEC FOR NEGATE
JRST [TLC FL,NEGF
TLO FL,DEMCHR ;MUST BE FOLLOWED BY A CHR
JRST READCH]
CAIN CS,"|" ;SEPERATOR?
JRST SEP
CAIN CS,"∞" ;ARBITRARY NUMBER
JRST ARBIT
CAIN CS,"∀" ;ANY?
JRST ANY
CAIN CS,"≡" ;QUOTE NEXT?
JRST [ILDB CS,T1
JUMPN CS,.+1 ;MUST HAVE ONE THERE
NERROR ISS] ;ELSE ILLEGAL
CAMN C,CS ;ARE THEY THE SAME
JRST ISTRU1 ;YES, CHECK NEGF
MOVE T5,CTBL(CS) ;GET BITS
TLNN FL,EXCTS1!EXCTSR ;EXACT?
TLNN T5,LETF⊗16 ;OR NOT LET
JRST ISFALS ;NO MATCH
XORI CS,40 ;CHECK OTHER CASE
CAMN C,CS
JRST ISTRU1
JRST ISFALS ;LOSE
MATCH: TLNE FL,DEMCHR ;DID WE NEED A CHARACTER THERE?
NERROR ISS ;YES, ILLEGAL STRING
JRST CPOPJ1 ;OK RETURN
ANY: CAIE C,15
JRST ISTRU ;YES THIS IS ANY CHR
ISFALS: CAIN C,15 ;IS IT A RETURN
AOSA T4 ;ADJUST COUNT AND ENTER A NULL STRING
IDPB C,T2 ;SAVE IN ARBIT
MOVEI T5,0
IDPB T5,T2
SUBI T4,2 ;COUNT THEM
JUMPLE T4,ILFMTR ;THIS LINE MUST HAVE ILLEGAL FORMAT
AOS ARBCNT ;ONE MORE SEEN
ISFAL1: TLNE FL,NEGF ;WAS NEG FLAG ON?
AOS (P) ;YES, A MATCH
POPJ P,
SEP: SKIPG T5,CTBL(C)
TRNE T5,NSEPF
JRST ISFALS ;NOT A SEP
ISTRU: CAIN C,15
AOSA T4
IDPB C,T2 ;SAVE CHR
MOVEI T5,0
IDPB T5,T2
SUBI T4,2
JUMPLE T4,ILFMTR
AOS ARBCNT
ISTRU1: TLNN FL,NEGF ;NEGATE?
AOS (P) ;NO, MATCH
POPJ P,
ILFMTR: MOVE T2,CPG ;GIVE HIM AN ERROR MESSAGE AND PAGE
PUSHJ P,PGPRN ;AND LINE
MOVE T1,(PNTR)
PUSHJ P,OUTSN
NERROR ILFMT
ARBIT: TLNN FL,NEGF ;THIS HAS NO MEANING
TLOE FL,ARBITG ;ARE WE SEEING ∞∞
NERROR ISS ;YES, ILLEGAL STRING
PUSH P,T1 ;SAVE SEARCH POINTER
MOVEI T5,0 ;SET ARBITRARY STRING TO NULL
IDPB T5,T2
SOJLE T4,ILFMTR
AOS ARBCNT
PUSH P,ARBCNT ;SAVE IN CASE WE COME BACK WITH NO MATCH
PUSH P,T2
PUSH P,T4
PUSH P,C
CHKTHS: TLO FL,DEMCHR ;NEED A CHARACTER NOW
PUSHJ P,READCH ;CALL SELF RECURSIVELY
JRST PROCED ;THIS COULD NOT MATCH JUST SCAN ON
MOVE T2,-3(P) ;RESTORE ARBIT COUNT
MOVEM T2,ARBCNT
MOVE T4,-1(P) ;AND ARBIT CHR COUNT
MOVE T2,-2(P) ;AND POINTER
PUSH P,ALTP ;SAVE CHR POINTER
TLZ FL,ARBITG ;CAN SEE ANOTHER ∞ NOW
PUSHJ P,LINMAT ;A MATCH
JRST RECUR ;NO, TRY FOR ANOTHER OF THAT CHR
SUB P,[XWD 7,7] ;GET ALL THAT JUNK OFF STACK
JRST CPOPJ1 ;AND RETURN TO CALLER OF LINMAT
RECUR: POP P,ALTP ;GET BACK POINTER
POP P,C ;AND CHR
MOVE T4,-2(P) ;RESTORE COUNT
MOVEM T4,ARBCNT
POP P,T4
POP P,T2 ;ALSO CHR COUNTER AND POINTER
DPB C,T2 ;PUT IN THAT CHR
MOVEI T5,0 ;AN@ TERMINATOR
IDPB T5,T2
SOJLE T4,ILFMTR
PUSH P,T2
PUSH P,T4 ;RESAVE
MOVE T1,-3(P) ;RESTORE SEARCH POINTER
ILDB C,ALTP ;GET ANOTHER CHR
PUSH P,C ;SAV IT
TLZ FL,NEGF ;TURN THIS OFF FOR RECURSION
CAIE C,12 ;END OF WORLD?
JRST CHKTHS
SUB P,[XWD 5,5] ;RECUCE STACK
POPJ P, ;AND ERROR RET
PROCED: TLZ FL,ARBITG!NEGF ;JUST GO ON
POP P,C
POP P,T4
POP P,T2
POP P,ARBCNT
POP P,(P) ;GET RID OF EXTRA POINTER
JRST CHRMAT ;CONTINUE MATCH SCANNING
BEND CHRMAT
BEND COMSRC
SUBTTL ERROR MESSAGE ROUTINES, UUO AND PDLOV HANDLERS
PDLOV: NERROR STC ;PUSH DOWN OVERFLOW
IFE TWOSGM,{
ERRHD: 0 ;THE ERROR HANDLER
}
ERRHDA: MOVEM T1,SVT1E ;SAVE T1 IN CASE OF RERROR
HRRZ T1,40 ;PICK UP THE ERROR NUMBER
SKIPE T1
CAILE T1,NUMER
ERROR ILUUO ;WRONG ERROR, CALL SELF
MOVEM T1,SVERN ;SAVE FOR =ERROR COMMAND
TRNE FL,EXTOG
SKIPA T1,ETBL-1(T1) ;(NN ZERO ERRORS) GET MESSAGE
MOVE T1,ETBL2-1(T1) ;GET LONG FORM
CALLI T1,3 ;AND PRINT
LDB T1,[POINT 9,40,8] ;GET UUO
CAILE T1,3
ERROR ILUUO ;IT WAS ILLEGAL
XCT ERND(T1) ;DO GOOD THING
JRST @ERRHD ;RERROR WILL FALL THROUGH XCT AND RETURN
ERND: ERROR ILUUO ;0 IS AN ERROR
HALT ;DIE
JRST COMND ;GO ON
MOVE T1,SVT1E ;RERROR- RESTORE T1
EDFLIN: MSG (T1,<TEMPORARY FILE IN USE. I GIVE UP>)
CALLI 12
NODSK: MSG (T1,<NO DISK AVAILABLE. PLEASE CHECK THE DISK YOU HAVE REQUESTED>)
CALLI 12
NOFIL: MSG (T1,FILE NOT FOUND)
JRST STPT
ILFN: MSG (T1,ILLEGAL FILE SPECIFICATION)
JRST STPT
DEFINE ERMS (A)
<FOR B⊂(A) <[ASCIZ /
*B*
/]
>>
ETBL: ERMS <ICN,DIE,DDE,ILC,ILUUO,LTL,NLN,NSP,ORDER,UNA,ILR>
ERMS <WAR,TMS,STL,ISS,ILFMT,NSG,FNF,DNA,NEC,IRS,STC,ITD>
ERMS <NNN,BKO>
NUMER←←.-ETBL
ETBL2: ERMS <INTERNAL CONFUSION,DEVICE INPUT ERROR>
ERMS <DEVICE OUTPUT ERROR,ILLEGAL COMMAND,ILLEGAL UUO>
ERMS <LINE TOO LONG>
[ASCIZ /
*NO SUCH LINE(S)*
/]
ERMS <NO SUCH PAGE>
ERMS <OUT OF ORDER,DEVICE NOT AVAILABLE,ILLEGAL REPLACEMENT>
ERMS <WRAP AROUND,TOO MANY STRINGS,STRING TOO LONG>
ERMS <ILLEGAL SEARCH STRING,ILLEGAL LINE FORMAT>
ERMS <NO STRING GIVEN,FILE NOT FOUND,DISK NOT AVAILABLE>
ERMS <INSUFFICIENT CORE AVAILABLE,ILLEGAL REPLACEMENT STRING>
ERMS <SEARCH STRING TOO COMPLEX,ILLEGAL TRANSFER DESTINATION>
ERMS <NO NEXT LINE,BREAK OUT>
SUBTTL TELETYPE I/O HANDLER, COMMAND PARSING ROUTINES
BEGIN GET2
;GET A PAIR OF FORM A/B,C/D LOLN IS SET BY CALLER BEFORE CALL
↑GET2S: PUSHJ P,SCAN
↑GET2: TRZ FL,CNTF ;NOT A ! COMMAND
PUSHJ P,GET1 ;GET A LINE AND PAGE NUMBER PAIR
MOVE T3,HIPG ;NOW SET LOWER PAGE TO THE ONE SEEN
MOVEM T3,LOPG
MOVE T3,HILN ;RESET LOW LINE IS A NUMBER SEEN
TRNE FL,LINSN
MOVEM T3,LOLN
↑GET2HF:MOVE T3,[ASCID /99999/] ;SET UP A LARGE NUMBER
TRNN FL,LINSN ;IF NO LINE NUMBER SEEN
MOVEM T3,HILN
TRZ FL,PGSN ;SO DELETE CAN DETECT A SECOND PAGE SPEC
CAIN C,"!" ;IS IT A ! COMMAND?
JRST GET2CT ;GO TAKE CARE OF IT
CAIE C,":" ;CHECK FOR SECOND SET
POPJ P, ;NOPE, RETURN
MOVEM T3,HILN ;SET HILN ANYWAY
JRST GETLAS ;AND GO GET THE SECOND PAIR
GET2CT: TRO FL,CNTF ;SET THE APPROPRIATE FLAG
PUSHJ P,SCAN ;THERE SHOULD BE A NUMBER HERE
TRNN FL,NUMF
NERROR ILC ;LOSE
MOVEM T2,SVCNT ;HANG ON TO IT
JRST SCAN ;SCAN NEXT AND RETURN
BEND GET2
BEGIN GET1
;ROUTINE SETS HIPG IN CASE NONE SEEN BY GETLA, THEN CALLS GETLA
↑GET1S: PUSHJ P,SCAN
↑GET1: MOVE T3,CPGL
MOVEM T3,HIPG
JRST GETLA
BEND GET1
BEGIN GETLA
;ROUTINE GETS A FULL SEQ NUMBER OF FORM A/B
↑GETLAS: PUSHJ P,SCAN
↑GETLA: TRZ FL,PGSN ;NO PAGE SEEN YET
PUSHJ P,GETL ;GET THE LINE NUMBER PART
MOVE T2,CPGL ;IN CASE LSRCH GOT A NEW PAGE
TRNE FL,PGSN ;DID LSRCH GET PAGE?
MOVEM T2,HIPG ;YES, USE IT
CAIE C,"/" ;IS THIS A PAGE COMMING?
JRST NOPG ;NO, A LINE NUMBER AT MOST
PUSHJ P,SCAN ;YES, GET THE PAGE NUMBER
SKIPLE T2 ;NUMBERS < OR = 0 LOSE
TRZN FL,NUMF ;WAS IT A NUMBER
NERROR ILC ;LOSE LOSE
TRO FL,PGSN ;YEP, WE SAW IT
MOVEM T2,HIPG ;SAVE THAT NUMBER
PUSHJ P,SCAN ;CHECK FOR + OR -
CAIN C,"+"
JRST PGPLS
CAIE C,"-"
JRST NOPG ;NO, GO DO ADSUB ON LINE NUMBER
PUSHJ P,SCAN ;GET THE NUMBER
TRZN FL,NUMF ;MUST BE A NUMBER
NERROR ILC
MOVE T1,HIPG
SUB T1,T2
MOVEM T1,HIPG ;FILL IN NUMBER
NOPGA: PUSHJ P,SCAN ;SCAN PAST NUMBER
NOPG: TRNN FL,LINSN!PGSN ;DID WE SEE A LINE OR A PAGE?
NERROR ILC ;NO, SOMETHING IS WRONG
PUSH P,T1 ;SAVE (HAVE ALREADY SCANNED)
PUSH P,T2
PUSHJ P,ADDSUB ;TAKE CARE OF + AND - FOR LINE
POP P,T2
POP P,T1
MOVEM SINDEX,HILN ;SAVE RESULT
POPJ P, ;AND RETURN
PGPLS: PUSHJ P,SCAN ;GET NUMBER TO ADD
TRZN FL,NUMF ;A NUMBER?
NERROR ILC ;NO, NERROR
ADDM T2,HIPG ;ADD IT IN
JRST NOPGA ;AND CLEAN UP
BEND GETLA
BEGIN GETL
;ROUTINE TO GET ONE LINE NUMBER FROM INPUT STREAM. HANDLES + AND -
↑GETLS: PUSHJ P,SCAN
↑GETL: TRZ FL,LINSN!ADDL!SUBL
TRZ FL2,STARF
CAIN C,"*"
JRST DOLST
CAIN C,200 ;DO WE HAVE TO SEARCH FOR IT
PUSHJ P,LSRCH ;OK THEN HERE WE GO
TRZN FL,NUMF
POPJ P, ;SCAN DID NOT SEE A NUMBER RETURN (CALLER CAN GIVER ERR)
MOVEM T1,HILN ;SAVE THE NUMBER HERE
GETL1: TRO FL,LINSN ;SET A FLAG TO SAY WE SAW THE LINE
PUSHJ P,SCAN ;SCAN FOR + OR -
CAIN C,"+"
JRST ADDNUM
CAIE C,"-"
POPJ P, ;NEITHER
TROA FL,SUBL ;SET SUBTRACT FLAG
ADDNUM: TRO FL,ADDL ;SET ADD FLAG
PUSHJ P,SCAN ;SCAN ANOTHER
TRZN FL,NUMF ;WAS IT A NUMBER
NERROR ILC ;ANYTHING ELSE IS ILLEGAL
MOVEM T2,SVINC ;SAVE IT
JRST SCAN ;RETURN AFTER SCANNING ONE MORE
DOLST: TRO FL2,STARF
JRST GETL1
BEND GETL
BEGIN ADDSUB
;ROUTINE TO RESOLVE THE + AND - IN THE LINE NUMBER. WE MUST WAIT
;UNTIL THE PAGE HAS BEEN DEFINED BEFORE DOING THIS
↑ADDSUB: MOVE SINDEX,HILN ;GET THE NUMBER
MOVE T1,HIPG ;GET THE REQUIRED PAGE
MOVEM T1,DPG ;AND SET IT AS THE DESIRED ONE
TRNN FL2,STARF
JRST DOAS
MOVE SINDEX,[ASCID /99999/] ;FIND A BIG LINE
PUSHJ P,FIND
CAME T1,[ASCID /99999/] ;IF ITS THERE ITS LAST
PUSHJ P,FINDB ;ELSE BACK UP
SKIPE T1 ;CHECK TO SEE IF EMPTY PAGE
CAMN T1,PGMK
SKIPA
MOVE SINDEX,T1 ;OK, USE ONE FOUND, ELSE LEAVE BIG
DOAS: TRZE FL,ADDL ;DID WE WANT TO ADD?
JRST ADLIN ;YES, GO ADD
TRZN FL,SUBL ;OR SUBTRACT?
↑CPOPJ: POPJ P, ;NO, RETURN
PUSHJ P,FIND ;GET THE DESIRED LINE
SUBL1: SOSGE SVINC ;DO WE WANT TO GO BACK STILL FARTHER
POPJ P, ;NO, ALL DONE
PUSHJ P,FINDB ;GET THE PREVIOUS LINE
SKIPE T1 ;0 MUST BE AT START OF BUFFER, QUIT
CAMN T1,PGMK ;WAS IT A PAGE MARK?
POPJ P, ;YES, AS FAR AS WE GO, SINDEX HAS CORRECT NUMBER
MOVE SINDEX,T1 ;THIS WILL DO
JRST SUBL1 ;GO TRY FOR MORE
ADLIN: PUSHJ P,FIND ;GET DESIRED LINE
CAME T1,PGMK ;WAS IT A PAGE MARK?
JUMPN T1,ADLIN1 ;OR 0 (I.E. END OF FILE)
POPJ P, ;RETURN WITH ORIGINAL NUMBER
ADLIN1: CAME T1,HILN ;SEE IF AN EXACT MATCH
SOS SVINC ;IF NO, ALREADY ARE +1
MOVE SINDEX,T1 ;GET THE WORD WE HAVE FOUND
ADLIN2: SOSGE SVINC ;NEED TO GO FURTHER
POPJ P, ;NO, RETURN RESULTS
PUSHJ P,FINDN ;GET THE NEXT LINE IN SEQUENCE
CAME T1,PGMK ;PAGE MARK?
JUMPN T1,.+2 ;OR EOF
POPJ P, ;YES, RETURN
MOVE SINDEX,T1 ;ACCEPT NEW NUMBER
JRST ADLIN2 ;AND LOOK FOR MORE
BEND ADDSUB
BEGIN LSRCH
COMMENT ⊗ ASSOCIATIVE LINE # ROUTINE -- WRITTEN BY SRS ⊗
;SEARCH FOR A LINE AND USE ITS NUMBER INSTEAD OF .
;MOSTLY PLAGIARIZED FROM SEARCH
↑LSRCH: PUSH P,SVINC ;SAVE PREVIOUSLY GATHERED LINE NUMBERS
PUSH P,SVCNT
PUSH P,HIPG
PUSH P,LOLN
PUSH P,LOPG
PUSH P,FL ;SAVE FLAGS IN CASE CALLED WITHIN SEARCH
PUSH P,FL2
TLZ FL,ASSMF ;CLEAR ALL FLAGS
SETZM LOLN ;JUST LIKE EVERYONE ELSE HAS TO
SETZM LLRCNT ;START WITH ZERO
SOSGE LSBUFN ;GET STRING BUFFER NUMBER
NERROR TMS ;NESTING TOO DEEP
MOVE T2,LSBUFN ;INDEX IN STRING BUFFER TABLES
MOVE T1,LSPTR(T2) ;SET UP BYTE POINTER
MOVE T3,LSPTT(T2) ;AND POINTER TO BYTE POINTER TABLE
PUSHJ P,SSTRNG ;GET A SEARCH STRING
JRST [MOVE T2,LSBUFN ;INDEX TO POINTERS
SKIPN @LSPTT(T2) ;WAS STRING SET?
NERROR NSG ;NO, TELL HIM
CAIN C,12
JRST ASSMD1 ;SPECIAL CONTINUE MODE
JRST .+1] ;YES, USE OLD ONE
TLZ FL,NUMSRF!DECID!EXCTSR ;CLEAR FLAGS
PUSHJ P,SCAN ;CHECK FOR WHAT COMES AFTER
TRNN FL,TERMF ;IF TERMINATOR
CAIN C,"," ;OR ,
JRST ASSMDT ;SET UP LIMITS SPECIALLY
CAIE C,"!"
CAIN C,":"
JRST ASSMDT ;LET HIM SPECIFY 2ND HALF OF RANGE
PUSHJ P,GET2 ;ELSE CALL USUAL LIMIT ROUTINE
SRC4: MOVE T1,HILN ;SAVE END OF RANGE
MOVEM T1,LLHILN
MOVE T1,HIPG
MOVEM T1,LLHIPG
CAIE C,"," ;ANY MORE ARGUMENTS?
JRST SRC1 ;NO, CHECK TERMINATOR AND PROCEED
PUSHJ P,SCAN ;YES, SEE WHAT IT IS
TRNN FL,IDF ;SHOULD BE IDENT OR NUMBER
JRST SRC2 ;NOT IDENT, CHECK FOR NUMBER OF SEARCHES
MOVS T1,ACCUM ;GET THE IDENT
CAIN T1,'N ' ;AND FIND OUT WHAT IT IS
TLO FL,NUMSRF!DECID
CAIN T1,'D '
TLO FL,DECID ;WANTS TO DECIDE ON LINE
TLNN FL,NUMSRF!DECID ;WAS IT EITHER?
JRST SRC3 ;NO, CHECK E
PUSHJ P,SCAN ;CONTINUE LOOKING
CAIE C,","
JRST SRC1 ;NO MORE ARGUMENTS
PUSHJ P,SCAN ;WELL WHAT KIND IS THIS ONE?
TRNN FL,IDF ;MORE IDENTS?
JRST SRC2 ;NO, MUST BE NUMBER OF SEARCHES
MOVS T1,ACCUM
SRC3: CAIE T1,'E '
NERROR ILC ;NO, HE MUST HAVE MADE A MISTAKE
TLO FL,EXCTSR ;YES, REMEMBER IT
PUSHJ P,SCAN ;AND CHECK FOR MORE
CAIE C,","
JRST SRC1 ;NO MORE
PUSHJ P,SCAN ;ONLY ONE THING IT CAN BE NOW
SRC2: TRNN FL,NUMF
NERROR ILC ;NOPE, LOSE
MOVEM T2,LLRCNT ;SAVE AS COUNT OF LINES TO FIND
PUSHJ P,SCAN ;GET TERMINATOR (WE HOPE)
SRC1: TRNN FL,TERMF ;ALLS WELL THAT ENDS WELL
NERROR ILC ;BUT THIS DOSNT
SRCH1A: MOVE T1,LSBUFN
MOVE T1,LSPTT(T1) ;GET POINTER TO STRINGS
PUSHJ P,CODSR ;AND GENERATE CODE
MOVE T1,LOPG ;GET SET TO HUNT IT
MOVEM T1,DPG
MOVEM T1,LLRPG ;FLAG TO SAY IF WE SHOULD PRINT PAGE
MOVE SINDEX,LOLN
PUSHJ P,FIND
TRZ FL,LINSN ;NO LINES YET
ONSRC: PUSHJ P,ONMOV ;CHECK RANGE
JRST ENDSRC ;DONE
TLZE FL,ASSMF ;FIRST TIME AND WANT .+1?
JRST [CAME T1,LOLN ;IS THERE EXACT MATCH?
JRST .+1 ;NO, THIS IS .+1
AOS SVCNT ;PRETEND WE DIDNT SEE IT
JRST SRNXT] ;AND TAKE NEXT
CAMN T1,PGMK ;PAGES ARE SPECIAL
JRST SRCPAG ;SO TAKE GOOD CARE OF THEM
MOVE T2,LSBUFN
MOVE T2,LSPTT(T2) ;POINTER TO STRINGS
PUSHJ P,COMSRC ;GO SEARCH THIS LINE
JRST SRNXT ;LOSER
MOVE T2,CPG ;GET CURRENT PAGE
CAME T2,LLRPG ;AND SEE IF WE SHOULD PRINT IT
PUSHJ P,PGPRN ;YES
MOVE T2,CPG ;NOW SET IT AS CURRENT
MOVEM T2,CPGL
MOVEM T2,LLRPG ;ALSO RESET FLAG
MOVE T2,(PNTR) ;ALSO SET LINE
MOVEM T2,CLN
TRO FL,LINSN ;WE SAW ONE
TLNN FL,DECID ;DOES HE WANT OPTION?
JRST SRNXTC ;NO, GO GET NEXT ONE OR STOP
TLNE FL,NUMSRF ;DO WE WANT ONLY LINE NUMBERS?
JRST SRCNUM ;YES
MOVE T1,PNTR ;GO PRINT LINE
PUSHJ P,OUTLIN
SRNXT1:
IFE FULDPX,<MOVEI T1,DDTINB ;READ
CALLI T1,1
LDB T1,[POINT 7,DDTINB,6] ;GET FIRST CHR
MOVEI T2,[ASCIZ /
/] ;GIVE HIM A RETURN
CALLI T2,3>
IFN FULDPX,<TTYUUO 0,T1
ANDI T1,177
TTYUUO 3,[ASCIZ /
/]>
CAIE T1,177 ;DID HE SAY RUBOUT(DO NOT USE)?
JRST LSOUT ;NO, WE'RE THROUGH
SRNXTC: SOSG LLRCNT ;HAVE WE FOUND ENOUGH
JRST LSOUT ;YES, GIVE UP (WE HAVE SEEN AT LEAST ONE)
SRNXT: PUSHJ P,FINDN ;GET NEXT LINE TO LOOK A
JRST ONSRC
SRCNUM: MOVE T1,(PNTR) ;PRINT SEQUENCE NUMBER
PUSHJ P,OUTSN
TERPRI (T1)
JRST SRNXT1 ;AND DECIDE
ENDSRC: TRZN FL,LINSN ;DID WE SEE ONE?
NERROR NLN ;NULL RANGE
JRST LSOUT
SRCPAG: AOS CPG ;JUST ADVANCE PAGE COUNTER
JRST SRNXT ;AND PROCEED
LSOUT: POP P,FL2 ;RESTORE THE FLAGS WE USED
POP P,T1
AND T1,[XWD ASSMF!NUMSRF!EXCTSR!DECID,ADDL!SUBL!CNTF]
ANDCM FL,[XWD ASSMF!NUMSRF!EXCTSR!DECID,ADDL!SUBL!CNTF]
IOR FL,T1
POP P,LOPG ;RESTORE PREVIOUS LINE NUMBERS
POP P,LOLN
POP P,HIPG
POP P,SVCNT
POP P,SVINC
MOVE T1,CLN ;LOAD CURRENT LINE AND PAGE WHICH WE FOUND
MOVE T2,CPGL
TRO FL, NUMF!PGSN ;AND MAKE LIKE SCAN SAW A NUMBER
AOS LSBUFN ;GO BACK TO SEARCH STRING ON PREVIOUS LEVEL IF ANY
POPJ P, ;AND EXIT VICTORIOUS
ASSMD1: TROA FL,CNTF ;MARK AS KEEP END OF RANGE
ASSMDT: TRZ FL,CNTF ;JUST IN CASE
TLO FL,ASSMF ;WE ASSUME .+1
MOVE T1,CLN ;SET THINGS UP FOR . TO INFINITY
MOVEM T1,LOLN
MOVEM T1,HILN ;AS GOOD AS ANYTHING WITH THE PAGE WE WILL
MOVE T1,CPGL ;USE
MOVEM T1,LOPG
TRZE FL,CNTF ;KEEP END?
JRST NOSPC ;YES
CAIE C,":" ;IF A : OR !
CAIN C,"!"
JRST HALFSP ;GET THE SECOND HALF (.+1 TO GIVEN)
MOVSI T1,377777 ;GET A LARGE PAGE
MOVEM T1,HIPG
JRST SRC4 ;BACK INTO THINGS
HALFSP: MOVEM T1,HIPG ;SET TOP AS /.
PUSHJ P,GET2HF ;GET THE SECOND HALF
JRST SRC4 ;AND GO
NOSPC: MOVE T1,LLHIPG
MOVEM T1,HIPG ;PUT BACK END
MOVE T1,LLHILN
MOVEM T1,HILN
JRST SRCH1A
LSPTR: FOR I←0,LSNUM-1
{POINT 7,LSBUF+(SRBLG/5+2)*I
}
LSPTT: FOR I←0,LSNUM-1
{LSPNT+SRNUM*I
}
BEND LSRCH
BEGIN SCAN
↑SCAN: TRZ FL,TERMF!NUMF!IDF ;RESET FLAGS
SKIPE CS,SAVCHR ;CHECK TO SEE IF WE LEFT ONE LAST TIME
JRST SL1 ;YES, IT MUST BE A DELIMITER
SKIPN C,SAVC ;BACK UP A CHARACTER?
JRST SL10 ;NO
PUSHJ P,GNCHB ;YES, GET BITS
SKIPA ;THIS STUFF HAS CORRECTED A DEFICIENCY IN THE ORIGINAL SCANNER
SL10: PUSHJ P,GNCH ;GET A CHR
SETZM SAVC
JUMPE CS,SL10 ;CHECK FOR TAB, SPACE, AND IGNORE
JUMPL CS,SL1 ;SPECIAL CHARACTER?
MOVE T3,[POINT 6,ACCUM] ;SET TO SAVE IDENT
SETZM ACCUM
TLNE CS,SNUMF⊗16 ;CHECK FOR NUMBER
JRST SNUM1 ;AND GO RACING OFF TO NUMBER ROUTINE
SL2P: TRO FL,IDF ;IT IS AN IDENT
SL2: TLNE T3,770000 ;HAVE WE STORED ENOUGH?
IDPB CS,T3 ;NO, STORE ANOTHER (RH OF CHR TABLE HAS SIXBIT)
PUSHJ P,GNCH ;CONTINUE
JUMPG CS,SL2 ;CHECK FOR ANOTHER NUMBER OR LETTER
SOK1: MOVEM CS,SAVCHR ;SAVE THE CHARACTER (MUST BE A SPECIAL CHR)
MOVEI C,0 ;ZERO IN C FOR NUMBERS AND IDENTS
POPJ P,
SL1: HRRZ C,CS ;FOR SPECIAL CHARACTERS, RETURN RH OF CTABLE
TLNE CS,TERM⊗16 ;CHECK FOR TERMINATOR
TRO FL,TERMF ;AND SET FLAG
ANDI C,377 ;GET RID OF EXTRA BITS
SETZM SAVCHR ;ZERO SAVCHR FOR LATER
CAIE C,"." ;CHECK FOR .
POPJ P, ;NO RETURN
MOVE T1,CLN ;SET UP FOR CURRENT LINE AND PAGE
MOVE T2,CPGL
TRO FL,NUMF ;CALL IT A NUMBER
POPJ P,
SNUM1: SETZB T1,T2 ;SET NUMBER ACCUMS TO 0
SN1A: TLNE T3,770000 ;WILL STORE THE SIXBIT FOR FILE NAMES
IDPB CS,T3 ;BUT ONLY IF LESS THAN 6
SN1B: LSH T1,7 ;ACCUMULATE ASCII IN T1
IOR T1,C
IMULI T2,=10 ;DECIMAL IN T2
ADDI T2,-"0"(C)
PUSHJ P,GNCH ;GET NEXT AND CONTINUE
JUMPLE CS,SOK2 ;CHECK FOR END OF NUMBER
TLNN CS,SNUMF⊗16 ;CHECK FOR NUMBER
JRST SL2P ;MUST BE AN IDENT
JRST SN1A ;CONTINUE SCANNING NUMBER
SOK2: TRO FL,NUMF ;IT WAS A NUMBER
LSH T1,1 ;CONVERT TO LINE NUMBER
IOR T1,[ASCID /00000/]
JRST SOK1 ;SAVE DELIM AND RETURN
BEND SCAN
; READ DATA LINE FOR INSERTION
BEGIN RDLIN
↑RDLIN: SETZM LIBUF+1 ;READ IN A LINE. FIRST ZERO INPUT BUFFER
MOVE T1,[XWD LIBUF+1,LIBUF+2]
BLT T1,LIBUF+MXWPL+1
MOVE T1,[POINT 7,LIBUF+1] ;SET UP POINTER
MOVEI T2,5*MXWPL-2 ;SET FOR AVAILABLE SPACE
MOVEI C,11 ;START WITH A TAB
JRST RDL3
RDL1: PUSHJ P,GNCH ;GET ANOTHER CHARACTER
CAIN C,15 ;IGNORE RETURN
JRST RDL1
CAIN C,12 ;LINE FEED IS THE ONLY PROPER END
JRST RDL2
CAIN C,200 ;ALTMODE IS A SPECIAL CASE
POPJ P, ;IT RETURNS WITHOUT MORE WORK
RDL3: IDPB C,T1 ;PUT IT IN THE BUFFER
SOJGE T2,RDL1 ;CHECK FOR OVERFLOW AND CONTINUE
RERROR LTL ;LINE IS TOO LONG
POPJ P, ;NON-SKIP RETURN
RDL2: MOVEI C,15 ;PUT IN A CR-LF
IDPB C,T1
MOVEI C,12
IDPB C,T1
HRRZS T1 ;NOW GET THE SIZE
SUBI T1,LIBUF-1
AOS (P) ;SKIP RETURN IF OK
POPJ P, ;AND RETURN
BEND RDLIN
BEGIN GNCH
↑GNCH: SOSG TIBUF+2 ;CHECK FOR BUFFER EMPTY
PUSHJ P,[TTYIN: IN TTY,0 ;GET MORE
POPJ P, ; NO PROBLEM
CLOSE TTY, ;CLEAR ALL BAD BITS
JRST TTYIN ];AND RETURN UNTIL HAVE
ILDB C,TIBUF+1 ;GET A CHR
CAIN C,175 ;CONVERT ALTMODE TO 200 TO DISTINGUISH FROM
MOVEI C,200 ;LEFT CURLY BRACKET
TRNN FL,DPYF ;IS THIS A DPY?
TLNE FL,QMODF ;NO, SHOULD WE TREAT ? SPECIALLY
JRST GNCHB ;NO
CAIN C,"?" ;SHOULD WE USE ALTERNATE CHR SET?
JRST GNCHA ;YES
↑GNCHB: JUMPE C,GNCH ;IGNORE NULLS
MOVE CS,CTBL(C) ;GET CHARACTER TABLE BITS
TLNE CS,LETF⊗16 ;CHECK TO SEE IF A LETTER
TDC C,CASEBT ;USE UPPER/LOWER INFO
POPJ P, ;NO, JUST RETURN
GNCHA: SOSG TIBUF+2 ;ALTERNATE CHR SET GET ANOTHER
PUSHJ P,TTYIN ;GET SOME MORE
ILDB C,TIBUF+1
SKIPE CTBL(C) ;NO CHANGE FOR NULL,SPACE, TAB, CRET
MOVS C,CTBL(C) ;GET THE ALTERNATE CHR FROM CHR TABLE
ANDI C,177 ;ONLY THE CHR BITS
JRST GNCHB ;GO CHECK THINGS
BEND GNCH
SUBTTL DISK FILE HANDLING ROUTINES
BEGIN FIND
;FIND-- PAGE TO FIND IS IN DPG. NUMBER TO FIND IS IN SINDEX.
;LOADS T1 WITH THE LINE NUMBER FOUND
;IF NO EXACT MATCH WILL FIND NEXT HIGHER NUMBER OR A PAGE MARK.
↑FIND: MOVE T1,DPG ;GET THE DESIRED PAGE
CAMLE T1,CPG ;IS IT GREATER THAN THE PAGE WE ARE ON
JRST FWDPG ;YES, SEARCH FORWARD FOR PAGE
CAML T1,CPG ;IS IT THE SAME AS THE CURRENT PAGE?
JRST FEQPG ;YES, JUST SEARCH FOR LINE NUMBER
SUBI PNTR,1 ;BACK UP A LITTLE (IN CASE POINTED AT PAGE MARK)
FIND1: SKIPN T1,(PNTR) ;GET THE WORD, BUT WATCH FOR START OF BUFFER
JRST FINDHD ;WILL HAVE TO FINISH COPY AND START OVER
CAME T1,PGMK ;IS IT A PAGE MARK?
SOJA PNTR,FIND1 ;CONTINUE SEARCHING
SOS T1,CPG ;DECREASE THE PAGE WE ARE NOW ON
CAME T1,DPG ;IS IT THE RIGHT ONE YET?
SOJA PNTR,FIND1 ;NO, KEEP SEARCHING
SUBI PNTR,1 ;BACK OVER PAGE MARK
FIND2: SKIPN T1,(PNTR) ;PICK UP WORD AND CHECK FOR START OF BUFFER
JRST FINDHD ;HAVE TO DO IT THE HARD WAY
TRNN T1,1 ;IS IT A SEQUENCE NUMBER?
SOJA PNTR,FIND2 ;NO, CONTINUE SEARCH
CAMN T1,PGMK ;IS IT PERHAPS A PAGE MARK?
AOJA PNTR,FNDFW1 ;YES, GO FORWARD A LINE AND RETURN IT
PUSHJ P,CHKREN ;DOES USER WANT OUT?
CAMGE SINDEX,T1 ;IS THE LINE WE WANT GREATER OR EQUAL TO THIS ONE
SOJA PNTR,FIND2 ;NO, KEEP UP THE GOOD WORK
CAMN SINDEX,T1 ;EXACT MATCH?
POPJ P, ;YES, RETURN
JRST FNDFW1 ;GO FORWARD A LINE TO GET NEXT LARGER
FEQPG: SKIPN T1,(PNTR) ;CHECK THE WORD WE ARE POINTING AT
JRST FNDFOO ;MUST BE POINTING AT END OF BUFFER OR BUFFER EMPTY
CAMN T1,PGMK ;IS IT A PAGE MARK?
SOJA PNTR,FIND2 ;MUST BE ONE AT END OF PAGE, SEARCH BACKWARDS
FEQPG1: CAMGE SINDEX,T1 ;COMPARE TO LINE WE WANT
JRST FIND2 ;WANT A SMALLER ONE, SEARCH BACK
JRST FNDFW1 ;SEARCH FORWARD
FWDPG: SKIPN T1,(PNTR) ;SEARCH FORWARD FOR PAGE
JRST FNXRCP ;END OF BUFFER, GET A NEW ONE
CAME T1,PGMK ;FOUND A PAGE MARK?
AOJA PNTR,FWDPG ;NO, CONTINUE
AOS T1,CPG ;ADVANCE CURRENT PAGE COUNT
CAME T1,DPG ;AND SEE IF WE ARE THER YET
AOJA PNTR,FWDPG ;NUTS, LOOK SOME MORE
ADDI PNTR,1 ;ADVANCE BEYOND PAGE MARK
FNDFW1:
FIND3: SKIPN T1,(PNTR) ;LOOK FOR LINE
JRST FNXRC ;END OF RECORD, GET A NEW ONE
TRNN T1,1
AOJA PNTR,FIND3 ;NOT LINE NUMBER
CAMN T1,PGMK ;PAGE MARK
POPJ P, ;RETURN IT, IT IS BEST MATCH WE CAN FIND
PUSHJ P,CHKREN ;DOES USER WANT OUT?
CAMLE SINDEX,T1 ;ARE WE THERE YET?
AOJA PNTR,FIND3 ;NO, CONTINUE SEARCH
POPJ P, ;YES, FINALLY
FNDFOO: CAMN PNTR,BUFP ;ARE WE POINTED TO START OF BUFFER
JRST FDFOO1 ;YES, BUFFER MUST BE EMPTY
SUBI PNTR,1 ;NO, MUST HAVE BEEN AT END OF BUFFER
FDFOO2: SKIPN T1,(PNTR) ;GET WORD
ERROR ICN ;MUST BE CONFUSED, THERE SHOULD BE A LINE NUMBER
TRNN T1,1 ;SEARCH FOR LINE NUMBER
SOJA PNTR,FDFOO2 ;KKEP LOOKING
CAMN T1,PGMK ;IS IT A PAGE MARK
AOJA PNTR,FNDFW1 ;YES, SEARCH FORWARD
JRST FEQPG1 ;GO DO SOMETHING WITH IT
FDFOO1: TRNE FL,EOF2 ;ARE WE AT END OF FILE?
JRST FINDHD ;WILL HAVE TO TRY FROM START
PUSHJ P,GETN ;GET THE NEXT BUFFER
JRST FEQPG
FNXRCP: TRNE FL,EOF2 ;ARE WE AT END OF FILE
JRST FNX1 ;YES, JUST RESET BGPG AND LOOK AGAIN
PUSHJ P,GETN ;GET THE NEXT BUFFER
JRST FWDPG ;AND CONTINUE SEARCH
FNX1: MOVE T1,CPG ;SET BGPG TO CURRENT PAGE
MOVEM T1,BGPG
TRO FL,BGSN ;RECORD THAT LARGEST PAGE SEEN
MOVEI T1,0 ;RETURN 0 FOR EOF
POPJ P,
FNXRC: TRNE FL,EOF2 ;ARE WE AT END OF FILE
JRST FNX1 ;YES, GIVE HIM BACK THE 0
PUSHJ P,GETN ;NO, GET THE NEXT BUFFER
JRST FIND3 ;AND CONTINUE LOOKING FOR LINE
↑FINDHD: TRNE FL,BOF ;ARE WE AT THE START OF THE FILE
JRST FNDFST ;YES, CAN NOT GO BACK JUST GIVE FIRST LINE OF FILE
TRNN FL,READOF ;DON'T BOTHER IN READ ONLY MODE
PUSHJ P,OCOMPL ;COMPLETE THE COPY
TLNE FL,COPFIL ;IS THIS A COPY
JRST FINDH4 ;YES, DON'T RELEASE IN AND OUT
RELEASE IN,0 ;RELEASE IO DEVICES
RELEASE OUT,0
INIT IN,14 ;AND GET THEM BACK
SIXBIT /DSK/
IBUF
JRST NODSK ;WHERE DID THE DISK GO, IT WAS HARE BEFORE
INIT OUT,14
SIXBIT /DSK/
XWD OBUF,0
JRST NODSK
MOVE T1,BUFHD ;SET UP JOBFF TO ESTABLISH BUFFERS
MOVEM T1,JOBFF
INBUF IN,=2
OUTBUF OUT,=2
TRNE FL,READOF ;ARE WE IN READ ONLY MODE?
JRST FINDH2 ;SET TO POINT TO ORIGINAL NAME AGAIN
MOVE T1,EDNAM
MOVEM T1,NAMO
MOVEM T1,NAMI
MOVSI T1,'TMP' ;AND EXTENSION
MOVEM T1,NAMO+1
MOVEM T1,NAMI+1
SETZM NAMO+2
SETZM NAMO+3
SETZM NAMI+3
LOOKUP IN,NAMI ;GET THAT FILE
JRST EDFLIN ;BUT IT JUST PUT ONE THERE
ENTER OUT,NAMO
JRST EDFLIN ;SOME OTHER BASTARD MUST BE USING IT
FINDH3: SETZM WC ;WC STARTS OUT 0
TRZ FL,EOF!EOF2 ;NOT AT EOF YET
TRO FL,BOF ;BUT ARE AT START OF FILE
TLO FL,FSTOPF ;SET FOR FIRST OP
TLZ FL,TECOF ;BUT NOT TECO
MOVEI T1,1 ;SET UP INPUT PAGE IN CASE OF
MOVEM T1,INPG ;ORDER OR LTL ERRORS ON INPUT
SETZM SVWD
SETZM OLDLIN ;USED IN CHECKING INPUT ORDER OF LINES
PUSHJ P,FILLBF ;FILL UP THE BUFFER
MOVEI T1,1
MOVEM T1,CPG ;START ON PAGE 1
MOVE PNTR,BUFP ;SET PNTR TO START OF WORLD
JRST FIND ;AND GO LOOKING
FNDFST: MOVE T1,@BUFP ;GET FIRST WORD
↑FNDFS1: MOVE PNTR,BUFP ;SET TO START OF WORLD
POPJ P, ;AND DISMISS
FINDH4: RELEASE ALTDV,0 ;LET GO OF ALTERNATE DEVICE
INIT ALTDV,14
SIXBIT /DSK/
ALTBF
JRST NODSK
MOVE T1,SVJRL2
MOVEM T1,JOBFF
INBUF ALTDV,2 ;ALL SET UP
FINDH2: MOVE T1,ORGNAM ;SET TO ORIGINAL NAME
MOVEM T1,NAMI
MOVE T1,ORGEXT
MOVEM T1,NAMI+1
MOVE T1,ORGPPN ;ALSO SAME PPN
MOVEM T1,NAMI+3
TLNE FL,COPFIL
JRST FINDH5
LOOKUP IN,NAMI
JRST NOFIL ;NO FKLE THERE START OVER
JRST FINDH3 ;GO ON
FINDH5: LOOKUP ALTDV,NAMI
JRST NOFIL
JRST FINDH3
BEND FIND
BEGIN FINDN
;FIND THE NEXT LINE, PAGE MARK, ETC.
↑FINDN1: SKIPN T1,(PNTR)
JRST FINDN2
TRNN T1,1
↑FINDN: AOJA PNTR,FINDN1
POPJ P, ;RETURN THE LINE
FINDN2: TRNE FL,EOF2 ;IS IT EOF?
POPJ P, ;YES, RETURN PRESENT T1 (0 FOR EOF)
PUSHJ P,GETN ;GET NEXT BUFFER
JRST FINDN1 ;GO LOOK SOME MORE
BEND FINDN
BEGIN FINDZ
FINDZ1: SKIPN T1,(PNTR) ;AS FINDN BUT STOPS AT END OF RECORD
POPJ P,
TRNN T1,1 ;LINE NUMBER?
↑FINDZ: AOJA PNTR,FINDZ1
POPJ P,
BEND FINDZ
BEGIN FINDB
;FIND THE PREVIOUS LINE
FINDB1: SKIPN T1,(PNTR) ;WATCH OUT FOR START OF BUFFER
JRST FINDB2
TRNN T1,1 ;LINE NUMBER?
↑FINDB: SOJA PNTR,FINDB1 ;TRY AGAIN
CAMN T1,PGMK ;TEST FOR PAGE MARK
SOS CPG ;NOW ON PREVIOUS PAGE
POPJ P, ;RETURN LINE NUMBER
FINDB2: TRNE FL,BOF ;AT START OF FILE?
JRST FNDFS1 ;YES, GO GET THE FIRST LINE OF FILE
MOVE T1,1(PNTR) ;GET THE FIRST LINE ON THIS PAGE
TRNN T1,1 ;MAKE SURE THERE IS ONE THERE
ERROR ICN ;NO, WE ARE CONFUSED
PUSH P,SINDEX ;SAVE (CALLER MAY NEED IT)
MOVE SINDEX,T1
SETOM NORENT ;DON'T PANIC OUT HERE.
PUSHJ P,FINDHD ;THIS WILL WORK AND WE WILL HAVE A LITTLE SPACE BEFORE
POP P,SINDEX ;GET THIS BACK
SOJA PNTR,FINDB1 ;GO LOOK BACK AGAIN
BEND FINDB
BEGIN FILLB
;CHECK TO SEE IF BUFFER TOO FULL AND DUMP IF NEEDED
↑FILLB: MOVE T1,WC ;GET WORD COUNT
FILLB3: CAMGE T1,MAXWC ;AND COMPARE WITH MAX PERMISSIBLE
POPJ P, ;OK, SO RETURN
MOVE T1,BUFP ;GET BUFFER POINTER
ADDI T1,1
FILLB1: SKIPN T2,(T1) ;FIND END OF FIRST LINE
JRST FILLB2
TRNN T2,1
AOJA T1,FILLB1
FILLB2: PUSHJ P,NOWFL ;PART OF GETN WILL DUMP AND ADJUST POINTERS
JRST FILLB ;SEE IF IN LIMITS NOW
BEND FILLB
BEGIN GETN
↑GETN: MOVE T1,WC ;GET THE NEXT BUFFER. FIND CURRENT WORD COUNT
CAMGE T1,HLFWC ;GREATER THAN HALF OF MAX POSSIBLE?
JRST FILLBF ;NO, JUST REFILL BUFFER
ASH T1,-1 ;YES, TAKE HALF OF IT
ADD T1,BUFP ;CONVERT TO POINTER
GETN1: SKIPN T2,(T1) ;LOOK FOR A WORD BOUNDARY
JRST NOWFL ;WE ARE HERE?
TRNN T2,1 ;SEQUENCE NUMBER?
SOJA T1,GETN1
↑NOWFL: PUSHJ P,DUMP ;DUMP IT
MOVE T2,T1 ;COPY POINTER
SUB T2,BUFP ;AND FIND OUT HOW MANY DUMPED
SUB PNTR,T2 ;ADJUST POINTER
EXCH T2,WC ;CALC NEW WORD COUNT
SUBB T2,WC
ADD T2,BUFP ;GET POINTER TO END OF BUFFER
HRLS T1 ;SET UP BLT
HRR T1,BUFP
BLT T1,(T2)
JRST FILLBF ;AND FINISH FILLIN BUFFER
BEND GETN
BEGIN OCOMPL
↑OCOMPL: MOVE T1,WC ;GET CURRENT WORD COUNT
ADD T1,BUFP ;TURN IT INTO A POINTER
PUSHJ P,DUMP ;DUMP DUMPS BUFFER FROM BUFP TO (T1)
SETZM WC ;TELL IT NO CURRENT WORD COUNT
TRNE FL,EOF2 ;ALL DONE?
POPJ P,
PUSHJ P,FILLBF ;FILL UP INPUT BUFFER
PUSHJ P,CHKREN ;DOES HE WANT OUT?
JRST OCOMPL ;AND GO DUMP THIS ONE TOO
BEND OCOMPL
↑CHKREN:
IFN 0,<
TLNN FL,ISCOP ;THERE ARE SOME CIRCUMSTANCES UNDER
SKIPN REENTSW ; WHICH NO ACTION SHOULD BE
POPJ P, ; TAKEN
PUSH P,T1 ;SAVE THIS DUDE
MOVEI T1,0 ;COPY IN PROGRESS IS ONE, NORENT ON
EXCH T1,NORENT ; IS ANOTHER
JUMPL T1,T1POPJ
MOVE T1,(PNTR) ;THIS LINE NUMBER
TRNE T1,1 ;IF NOT A LINE NUMBER,
CAMN T1,PGMK ; OR IF A PAGE MARK, DON'T DO IT
JRST T1POPJ ; THAT'S ABOUT ENOUGH OF THAT
SETZM REENTSW ;ONCE ONLY
MOVEM T1,CLN ;MAKE THE LINE WE STOPPED ON
MOVE T1,CPG ; INTO "./."
MOVEM T1,CPGL
OUTPUT TTY, ;FORCE OUTPUT
PUSHJ P,PGPRN ;PRINT PAGE NUMBER
MOVE T1,PNTR ;SET UP TO PRINT LINE
PUSHJ P,OUTLIN ; AND THE LINE WE STOPPED ON
OUTPUT TTY, ;FORCE OUTPUT AGAIN
TTYUUO 11,0 ;CLEAR ANY REMAINING COMMANDS OR ANYTHING
NERROR BKO ;"BREAK OUT" AND GET NEXT COMMAND
T1POPJ: POP P,T1
>
POPJ P,
BEGIN DUMP
↑DUMP: MOVE T2,BUFP ;DUMP BUFFER FROM BUFP TO (T1)
CAMGE T2,T1 ;CHECK TO SEE IF WE ARE DUMPINF ANYTHING
TRZ FL,BOF ;IF SO TURN OFF BOF
TRNN FL,READOF ;RETURN IF READ ONLY MODE
DUMP1: CAML T2,T1 ;MORE TO DO?
POPJ P, ;NO, RETURN
PUSH P,T1 ;SAVE FOR LATER
MOVEI T1,1(T2) ;FIND END OF THIS LINE
DUMP3: SKIPN T3,(T1) ;ANY OLD END WILL DO
JRST DUMP2
TRNN T3,1 ;SUCH AS A LINE NUMBER
AOJA T1,DUMP3 ;NOT YET
DUMP2: SUB T1,T2 ;GET LENGTH
CAML T1,OBUF+2 ;WILL IT FIT?
PUSHJ P,OUTDO ;NO, DUMP CURRENT BUFFER
DUMP4: MOVE T3,(T2) ;PICK UP WORD
PUSHJ P,OUTWD
ADDI T2,1 ;ADVANCE POINTER
SOJG T1,DUMP4 ;AND CHECK COUNT
POP P,T1
JRST DUMP1 ;GO CHECK FOR END
BEND DUMP
BEGIN OUTWD
↑OUTWD: SOSG OBUF+2 ;CHECK WORDS LEFT
PUSHJ P,OUTDO
OUTWD1: IDPB T3,OBUF+1 ;OUTPUT IT
POPJ P, ;AND RETURN
↑OUTDO: OUTPUT OUT,0
STATO OUT,760000 ;CHECK FOR ERRORS
POPJ P,
ERROR DDE ;YES, GIVE ERROR AND BOMB OUT
BEND OUTWD
BEGIN FILLBF
↑FILLBF: MOVE T1,WC ;GET WORD COUNT
ADD T1,BUFP ;AND CONVERT TO POINTER TO END OF BUFFER
FILBF3: CAML T1,FILPT ;FULL ENOUGH?
POPJ P, ;YES, RETURN
TLNE FL,TECOF ;SPECIAL READING FOR TECO FILES
JRST RDTECO
HRLI T1,-MXWPL-2 ;GET A COUNT FOR MAX LINE SIZE
SKIPN T3,SVWD ;SEE IF THERE IS A WORD LEFT FROM LAST TIME
PUSHJ P,GETWD ;ELSE GET A NEW ONE
JUMPE T3,SNEOF ;MUST BE EOF
TLZE FL,FSTOPF ;IF FIRST OP
JRST CKTECO ;CHECK FOR TECO FILE
NOTECO: MOVEM T3,SVWD2 ;SAVE FOR SEQUENCE CHECK
JRST FILBF4 ;GO PUT IT AWAY
FILBF1: PUSHJ P,GETWD ;ELSE GET A NEW ONE
JUMPE T3,FILBF2 ;0 WORD MUST BE EOF
TRNE T3,1 ;CHECK FOR SEQNUM
JRST FILBF2 ;YES, FINISH PUTTING IT IN
FILBF4: MOVEM T3,(T1) ;PUT IN THIS WORD
AOS WC ;AND ADVANCE WORD COUNT
AOBJN T1,FILBF1 ;ADVANCE POINTER AND CHECK COUNT
JRST INLTL ;LINE IS TOO LONG
FILBF2: MOVEM T3,SVWD ;SAVE THIS WORD
FILBF0: SETZM (T1) ;MAKE SURE OF A ZERO WORD
HRRZS T1 ;ELIMINATE COUNT INFO
MOVE T3,SVWD2 ;CHECK ON ORDER OF INPUT LINES
CAMN T3,PGMK ;WAS IT A PAGE MARK?
SETZM OLDLIN ;RESET LINE LAST INPUT
CAMG T3,OLDLIN ;CHECK FOR CORRECT ORDER
JRST OUTOFO ;LINES ARE OUT OF ORDER
FILBF5: MOVEM T3,OLDLIN ;SAVE FOR LATER
CAMN T3,PGMK ;ADVANCE INPUT PAGE
AOS INPG
SKIPE SVWD ;CHECK TO SEE IF WAS EOF
JRST FILBF3 ;AND TRY FOR MORE
SNEOF: SETZM (T1) ;MAKE SURE OF ZERO WORD
TRO FL,EOF2 ;SET EOF FLAG
MOVE T1,INPG ;GET INPUT PAGE
MOVEM T1,BGPG ;AND SET LARGEST PAGE
TRO FL,BGSN
SETZM SVWD ;ALSO ZERO EXTRA WORD
POPJ P, ;AND RETURN
INLTL: PUSHJ P,GETWD ;FIND THE END OF THE LINE ON INPUT
JUMPE T3,INLTL2 ;THIS IS IT
TRNN T3,1 ;OR MAYBE THIS
JRST INLTL ;KEEP LOOKING
INLTL2: MOVEM T3,SVWD ;SAVE IT
PUSH P,T1 ;SAVE POINTER TO END OF IT
SUBI T1,2 ;LAST PART THAT IS IN THE LINE
MOVEI T2,<BYTE (21)0(7)15,12> ;A CRLF
DPB T2,[POINT 15,(T1),35] ;MAKE SURE IT ENDS PROPERLY
INLTL1: SKIPN T2,(T1) ;NOW LOOK FOR THE START OF IT
ERROR ICN ;SOMETHING HAS GONE WRONG, THERE IS NO LINE #
TRNN T2,1 ;START?
SOJA T1,INLTL1 ;NO, TRY AGAIN
MOVE T2,INPG ;PRINT HIM THE CURRENT PAGE
PUSHJ P,PGPRN
PUSHJ P,OUTLIN ;PRINT THE LINE
RERROR LTL ;AND THE ERROR MESSAGE
POP P,T1 ;RESTORE POINTER TO END
SOS WC ;GET WORD COUNT CORRECTED
SOJA T1,FILBF0 ;AND CONTINUE FILL
OUTOFO: PUSH P,T1 ;SAVE THE POINTER
PUSH P,T3 ;SAVE T3 ALSO
SUBI T1,1 ;GET BACK INTO LINE
OUTOF1: SKIPN T2,(T1) ;LOOK FOR START OF LINE
ERROR ICN ;HORRIBLE CONFUSION
TRNN T2,1 ;CHECK FOR SEQ NUM
SOJA T1,OUTOF1 ;NOPE, TRY SOME MORE
MOVE T2,INPG ;PRINT HIM THE PAGE
PUSHJ P,PGPRN
PUSHJ P,OUTLIN ;PRINT THE LINE
RERROR ORDER ;GIVE HIM SOMETHING TO THINK ABOUT
POP P,T3 ;RESTORE
POP P,T1 ;GET SET TO GO ON
JRST FILBF5 ;GO
CKTECO: TRNE T3,1 ;CHECK FOR A LINE NUMBER
JRST NOTECO ;NO ITS NOT A TECO FILE
TLO FL,TECOF ;SET WARNING FLAG
TLNE FL,COPFIL ;IS IT ANOTHER FILE?
JRST CKTEC2 ;SPECIAL CHECK
SETSTS IN,0 ;SET FOR CHAR AT A TIME INPUT
MOVSI T3,(<POINT 7,0>)
HLLM T3,IBUF+1 ;SET INPUT BYTE POINTER
MOVEI T3,5 ;COMVERT TO CHRS
IMULM T3,IBUF+2
AOS IBUF+2 ;AND COMPENSATE FOR THINKING WE TOOK ONE
↑RDTECO:HRRZM T1,TMPT1 ;SAVE THIS FOR A WHILE
MOVEI T3,1(T1) ;ZERO OUT A FEW WORDS
HRL T3,T1
SETZM (T1)
BLT T3,MXWPL(T1)
ADDI T1,1 ;THIS IS WHERE CHRS SHOULD BE PUT
PUSH P,T1 ;SAVE
MOVE T1,SVWD ;LAST LINE NUMBER
MOVE T2,[ASCID /00100/]
PUSHJ P,ASCIAD
MOVEM T1,SVWD ;SAVE FOR LATER
MOVEM T1,SVWD2 ;AND FOR ORDER CHECK
CAMGE T1,[ASCID /00100/] ;CHECK WAR
JRST INSPG1 ;FORCE PAGE INSERT
EXCH T1,(P) ;GET OLD T1 BACK AND SAVE NUMBER
MOVEI T2,MXWPL*5-2 ;COUNT
MOVEI T3,11 ;FIRST CHR
HRLI T1,(<POINT 7,0>)
IDPB T3,T1
LINL1: PUSHJ P,GETWD ;NEXT CHR
CAIN T3,15
JRST LINL1 ;IGNORE RETURNS
CAIN T3,14
JRST IPGMK ;GO PUT IN A PAGE MARK
JUMPE T3,EOF1 ;MUST BE END OF FILE
POP P,-1(T1) ;PUT NUMBER IN PROPER PLACE
JRST LP1 ;AND READ MORE OF LINE
CLP: PUSHJ P,GETWD
LP1: CAIN T3,15 ;IGNORE RETURNS
JRST CLP
CAIE T3,0 ;FOR EOF
CAIN T3,12 ;OR LINE FEED
JRST LINFD ;GO PUT IN RETURN LINE FEED
IDPB T3,T1 ;ELSE DEPOSIT
SOJG T2,CLP ;HAVE WE RUN OUT
ADD T1,[XWD 70000,0] ;BACK UP POINTER
COMMENT/ THE ABOVE LINE WAS MODIFIED BY R. GORIN 9 MAY 1971
IT FORMERLY READ ADD T1,[XWD 700,0] ;BACK UP POINTER
IT IS CLEAR TO ME THAT THE ORIGINAL LINE DID NOT FUNCTION RIGHT
/
TLZ FL,TECOF ;USE THE ABSENCE AS A FLAG
PUSHJ P,GETWD
CAIE T3,12
JUMPN T3,.-2
LINFD: MOVEI T3,15
IDPB T3,T1
MOVEI T3,12
IDPB T3,T1
MOVEI T1,1(T1)
MOVE T3,T1
SUB T3,TMPT1 ;GET COUNT
ADDM T3,WC
TLOE FL,TECOF ;IF OFF WE HAD A LTL ERR
JRST FILBF0 ;THIS WILL FINISH UP
PUSH P,T1 ;SET UP FOR LTL CODE
AOS WC
AOS (P)
SOJA T1,INLTL1
INSPG1: POP P,T1
SKIPA
IPGMK: POP P,T2 ;GET RID OF IT
MOVEI T3,1 ;SO IT WILL NOT BE EOF
MOVEM T3,SVWD ;SO WE START OVER
MOVE T3,PGMK
MOVEM T3,SVWD2
MOVEM T3,-1(T1)
MOVEI T2,2
ADDM T2,WC
MOVE T3,[BYTE (7) 15,15,14]
MOVEM T3,(T1)
AOJA T1,FILBF0 ;DONE
EOF1: POP P,T2 ;CLEAR STACK
SOJA T1,SNEOF
BEND FILLBF
BEGIN GETWD
↑GETWD: TRNE FL,EOF
JRST RTEOF ;RETURN 0 IF EOF
TLNE FL,COPFIL ;IN A COPY, WE GET FROM SOMEWHERE ELSE
JRST COPGET
SOSG IBUF+2 ;CHECK FOR MORE WORDS
JRST GETDO ;NO, GET SOME BY INPUT
GETWD1: ILDB T3,IBUF+1 ;PICK UP A WORD
JUMPE T3,GETWD ;IGNORE 0 WORDS
POPJ P, ;RETURN
GETDO: INPUT IN,0
STATO IN,760000 ;CHECK FOR ERRORS AND EOF
JRST GETWD1
STATZ IN,740000 ;ERROR?
ERROR DIE ;YES, INPUT ERROR
TRO FL,EOF ;NO, MUST BE EOF
RTEOF: MOVEI T3,0 ;RETURN 0
POPJ P,
BEND GETWD
BEGIN ONMOV
;CHECK TO SEE IF OUT OF LIMITS SKIP RETURN IF OK
↑ONMOV: JUMPE T1,CPOPJ ;0, MUST BE EOF SO ALL DONE
PUSHJ P,CHKREN ;DOES HE WANT OUT?
MOVE T2,CPG ;GET THE CURRENT PAGE
CAMN T1,PGMK ;ARE WE AT A PAGE MARK?
ADDI T2,1 ;YES, TREAT AS NEXT PAGE
TRNE FL,CNTF ;IS THIS A ! TYPE COMMAND?
JRST ONCNT
CAMLE T2,HIPG ;HOW DOES IT COMPAGE WITH UPPER LIMIT
POPJ P, ;HIGHER, ALL DONE
CAME T1,PGMK ;IF PAGE MARK, DO NOT COMPARE LINE
CAME T2,HIPG ;OR IF NOT ON LAST PAGE
SKIPA
CAMG T1,HILN ;ARE WE OUT OF LINES?
AOS (P) ;SKIP RETURN ALL OK
POPJ P, ;GO
ONCNT: CAMN T1,PGMK ;DO NOT COUNT PAGE MARKS
SKIPG SVCNT ;IF PAGE MARK, GIVE UP IF DONE
SOSL SVCNT ;ARE WE OUT
AOS (P) ;SKIP RETURN FOR OK
POPJ P,
BEND ONMOV
BEGIN INSED
;INSERT A LINE (IN LIBUF) INTO PLACE POINTED AT BY PNTR
;WORD COUNT OF OLD LINE IN OCNT. OF NEW LINE IN NCNT
↑INSED: MOVE T1,NCNT ;SEE HOW THE COUNTS DIFFER
SUB T1,OCNT
JUMPE T1,NOBLT ;THEY ARE SAME, NO MOVING NECESSARY
JUMPG T1,BBLT ;NEW IS LARGER, BLT WILL NOT DO
MOVE T2,PNTR ;SET UP BLT POINTER FROM PNTR+OCNT
ADD T2,OCNT
HRLS T2
HRR T2,PNTR ;TO PNTR+NCNT
ADD T2,NCNT
ADDB T1,WC ;ADJUST WC TO OLD WORD COUNT +NCNT-OCNT
ADD T1,BUFP ;LAST TRANSFERED IS BUFP+WC+NCNT-OCNT
BLT T2,(T1)
NOBLT: SKIPN T1,NCNT ;CHECK FOR 0 NEW COUNT (WE ARE DELETING)
POPJ P, ;IF SO DONE
MOVE T2,PNTR ;GET THE POINTER POSITION FOR BLT
HRLI T2,LIBUF ;FROM LIBUF TO PNTR
ADD T1,PNTR ;STOP AT PNTR+NCNT-1
BLT T2,-1(T1)
POPJ P, ;AND ALL DONE
BBLT: MOVE T2,BUFP ;FAKE BACKWARDS BLT FROM BUFP+WC
ADD T2,WC
ADDB T1,WC ;TO BUFP+WC+NCNT-OCNT (ALSO FIX WC)
ADD T1,BUFP
BBLT1: CAMGE T2,PNTR ;STOP HERE (COULD STOP SOONER BUT THIS IS EASIER)
JRST NOBLT ;AND GO MOVE IN NEW STUF
MOVE T3,(T2) ;TRANSFER A WORD
MOVEM T3,(T1)
SUBI T1,1
SOJA T2,BBLT1 ;AND KEEP IT UP
BEND INSED
BEGIN GETLTH
↑GETLTH: MOVE T1,PNTR ;GET THE LENGTH OF THE LINE POINTED AT
ADDI T1,1
GETLN1: SKIPN T2,(T1) ;ANY END IS GOOD ENOUGH
JRST GETLN2
TRNN T2,1 ;SEQ-NUM?
AOJA T1,GETLN1
GETLN2: SUB T1,PNTR ;FIND LENGTH
POPJ P, ;AND RETURN
BEND GETLTH
SUBTTL TELETYPE OUTPUT ROUTINES
BEGIN OUTLIN
↑OUTLIN: TRNE FL2,SUPN ;ARE WE SUPPRESSING LINE NUMBERS?
AOS T1 ;YES, SKIP IT
HRLI T1,(<POINT 7,0>) ;GET SET TO PRINT A LINE
TRNE FL2,SUPN ;IF SUPPRESSING LINE NUMBERS
IBP T1 ;ALSO SUPPRESS THE TAB WHICH FOLLOWS
SKIPE SCRUP2 ;SCRUP OK?
SOSLE SCRUP1
JRST .+2 ;OK THIS TIME
JRST BUNKO
OUTL1: ILDB C,T1 ;GET A CHR
PUSHJ P,OCHR ;AND PRINT IT
CAIE C,12 ;IS IT LINE FEED
JRST OUTL1 ;NO, CONTINUE
OUTPUT TTY,0 ;FLUSH IT
POPJ P,
BUNKO: PUSH P,T2 ;SAVE T2 ON STACK
PUSH P,T3 ;SAVE ANOTHER
MOVE T2,T1 ;SAVE OLD POINTER
IBP T2 ;POINTER TO FIRST CHARACTER
MOVEI T3,0 ;INITIALIZE COUNT MAX 89 CHARS
BUNK1: ILDB C,T1 ;LOAD BYTE
CAIN C,11 ;IS THIS A TAB
TRO T3,7 ;TURN ME ON
CAIE C,12 ;LINE FEED STOPS ALL
AOJA T3,BUNK1 ;COUNT AND LOOP
SUBI T3,=83
MOVN T3,T3
PUSHJ P,DECBP ;DECREMENT POINTER, POINTS TO CR
CAMN T1,T2 ;ARE THESE THE SAME?
JRST BUNK3 ;ALL DONE
MOVEI C," "
SOJL T3,BUNK2 ;NO SPACES
PUSHJ P,OCHR
JRST .-2 ;LOOP
BUNK2: PUSHJ P,DECBP
LDB C,T1
PUSHJ P,OCHR
CAME T1,T2
JRST BUNK2
BUNK3: POP P,T3
POP P,T2
MOVEI C,15
PUSHJ P,OCHR
MOVEI C,12
PUSHJ P,OCHR
OUTPUT TTY,
CALLI C,22
ANDI C,37
ADDI C,10
MOVEM C,SCRUP1
POPJ P,
DECBP: ADD T1,[XWD 070000,0] ;PUSH IT BACK
SKIPG T1 ;SKIP IF OK
SUB T1,[XWD 430000,1] ;MAJIC
POPJ P,
BEND OUTLIN
PGPRN: MSSG (T3,<
PAGE >)
PUSHJ P,DPRNT ;PRINT THE NUMBER IN T2
OUTPUT TTY,0 ;FLUSH TTY OUTPUT
TERPRI (T3) ;RETURN
POPJ P,
OUTSN: MOVEM T1,SQBUF ;PUT IT IN SPACE FOLLOWED BY A TAB
IFEDUPL,<MOVEI T3,SQBUF
CALLI T3,3;> TTYUUO 3,SQBUF ;ONE OR 'TOTHER
POPJ P,
↑DECPR: IDIVI T1,=10 ;THE USUAL DECIMAL PRINTER
HRLM T2,(P)
SKIPE T1
PUSHJ P,DECPR
HLRZ C,(P)
ADDI C,"0"
JRST (T3) ;EXCEPT HAS ARBITRARY OUTPUT ROUTINE
;THE USUAL NUMBER PRINTER
DPRNT: IDIVI T2,=10
HRLM T3,(P)
SKIPE T2
PUSHJ P,DPRNT
HLRZ C,(P)
ADDI C,"0"
IFE FULDPX,<JRST OCHR>
IFN FULDPX,<TTYUUO 1,C
POPJ P,>
;INPUT IN T2, PRINTS TO TTY -- USES T1 (SIXBIT→ASCII)
SIXLJ1: JUMPE T2,SIXPRT ;NO USE IF 0
LSH T2,6 ;SHIFT NEXT CHAR IN
↑↑SIXLJP: TLNN T2,770000 ;LEFT-JUSTIFIED?
JRST SIXLJ1 ;NO, CONTINUE
↑↑SIXPRT: MOVEI T1,0
LSHC T1,6 ;GET NEXT CHAR
JUMPE T1,CPOPJ ;DONE
ADDI T1,40 ;CONVERT TO ASCII
TTYUUO 1,T1 ;PUT OUT CHAR
JRST SIXPRT
BEGIN OCHR
;CHARACTER OUTPUT
↑OCHR: MOVE CS,CTBL(C) ;GET THE MAJIC BITS
TLNE CS,LETF⊗16 ;CHECK FOR LETTER
TDC C,CASEBT ;AND CHANGE CASE AS NECESSARY
trnn fl2,supn ;is this a pretty print? if so no ? conversion.
TRNE FL,DPYF ;IS IT A DISPLAY
JRST OCH2 ;YES, JUST PRINT
PUSH P,C ;SAVE THE CHARACTER
LDB C,[POINT 7,CTBL(C),10] ;GET PRINT EQUIV.
JUMPE C,OCH1 ;NONE, PRINT ORIGINAL
TDNE CS,[XWD LETF⊗16,M37] ;IS THIS A LETTER OR SPECIAL
TRNN FL,M37F ;AND A MODEL 37
SKIPA
JRST OCH1 ;THEN PRINT NORMALLY
MOVEM C,(P) ;SAVE IN STACK
MOVEI C,"?"
SOSG TOBUF+2
OUTPUT TTY,0
IDPB C,TOBUF+1 ;OUTPUT THE CHR
OCH1: POP P,C ;GET THE CHR TO PRINT
OCH2: SOSG TOBUF+2
OUTPUT TTY,0
IDPB C,TOBUF+1
POPJ P, ;AND RETURN
BEND OCHR
SUBTTL VERY CLEVER WFW ROUTINES FOR LINE NUMBER ARITHMETIC
BEGIN ASCIAD
↑ASCIAD: AND T2,K2A ;CONVERT TO NUMBERS
IOR T1,K4A ;MAKE SURE THIS IS IN DIGIT FORM
ADD T1,K1A ;GET EACH DIGIT IN RANGE 166 TO 177 FOR CARRY
ADD T2,T1 ;SUM
AND T2,K3A ;GET RID OF 100 BITS IF THERE
MOVE T1,K4A ;FIND OUT WHICH ONES NEED SUBTRACTING
AND T1,T2
ASH T1,-3 ;CONVIENIENTLY THEY NEED 6 SUBTRACTED
SUBM T2,T1 ;SO DO IT
IOR T1,K4A ;AND RECONVERT TO DIGITS
POPJ P, ;WE HAVE ADDED THE ASCII IN T1 AND T2 RESULT IN T1
K1A: BYTE (7) 106,106,106,106,106
K2A: BYTE (7) 17,17,17,17,17
K3A: BYTE (7) 77,77,77,77,77
K4A: ASCID /00000/
K5A: BYTE (7) 7,7,7,7,7
K6A: BYTE (1) 1 (7) 77,77,77,77,77
K7A: BYTE (1) 0 (7) 106,106,106,106,106
↑ASCAV: AND T2,K2A
IOR T1,K4A ;THIS ROUTINE AVERAGES 2 ASCII NUMERS
LSH T1,-1
ADD T1,K7A ;IT WORKS MOSTLY BY MAJIC
LSH T2,-1
ADD T2,T1
AND T2,K6A
MOVE T1,T2
ANDCM T1,K3A
AND T2,K3A
MOVE T3,T2
LSH T3,-3
AND T3,K2A
AND T2,K5A
SUB T2,T3
LSH T1,-4
ADD T2,T1
LSH T1,-2
ADD T2,T1
IOR T2,K4A
POPJ P,
BEND ASCIAD
SUBTTL CHARACTER TABLE FOR SCANNER
;A CHARACTER TABLE FOR USE ON TYPE IN AND TYPE OUT
;FLAGS USED IN CHARACTER TABLE
OPF←←10 ;THIS IS A SPECIAL CHARACTER
SNUMF←←4 ;THIS IS PART OF A NUMBER
LETF←←2 ;THIS IS A LETTER
TERM←←1 ;THIS IS A TERMINATOR
M37←←400000 ;THIS CHR IS PRINTED AS ITSELF ON MODEL 37
NSEPF←←200000 ;THIS IS NOT A SEPERATOR (USED ON $,%,AND.)
DEFINE CHRS (FLAGS,PALT,INALT,RH)
<BYTE (4) FLAGS (7) PALT,INALT(18)RH>
CTBL: 0
CHRS OPF,"!","↓","↓"
CHRS OPF,42,"α","α"
CHRS OPF,"#",3,3
CHRS OPF,"$",4,4
CHRS OPF,"%",5,5
CHRS OPF,"&",6,6
CHRS OPF,"'",7,7
CHRS OPF,"(",10,10
0
CHRS OPF!TERM,0,12,12
CHRS OPF,0,13,13
CHRS OPF,0,14,14
0
CHRS OPF,")",16,16
CHRS OPF,"*",17,17
CHRS OPF,"+",20,20
CHRS OPF,{","},21,21
CHRS OPF,"-",22,22
CHRS OPF,".",23,23
CHRS OPF,"/",24,24
CHRS OPF,"0",25,25
CHRS OPF,"1",26,26
CHRS OPF,"2",27,27
CHRS OPF,"9",30,30
CHRS OPF,"6",31,31
CHRS OPF,"4",32,32
CHRS OPF,"=",33,33
CHRS OPF,"<",34,34
CHRS OPF,\">",35,35
CHRS OPF,"7",36,36
CHRS OPF,"8",37,37
0
CHRS OPF,0,1,"!"
CHRS OPF,0,2,42
CHRS OPF,0,3,"#"
CHRS OPF,0,4,"$"+NSEPF
CHRS OPF,0,5,"%"+NSEPF
CHRS OPF,0,6,"&"
CHRS OPF,0,7,47
CHRS OPF,0,10,"("
CHRS OPF,0,16,")"
CHRS OPF,0,17,"*"
CHRS OPF,0,20,"+"
CHRS OPF,0,21,{","}
CHRS OPF,0,22,"-"
CHRS OPF,0,23,"."+NSEPF
CHRS OPF,0,24,"/"
CHRS SNUMF,0,25,20
CHRS SNUMF,0,26,21
CHRS SNUMF,0,27,22
CHRS SNUMF,0,175,23
CHRS SNUMF,0,32,24
CHRS SNUMF,0,"5",25
CHRS SNUMF,0,31,26
CHRS SNUMF,0,36,27
CHRS SNUMF,0,37,30
CHRS SNUMF,0,30,31
CHRS OPF,0,174,":"
CHRS OPF,0,{";"},{";"}
CHRS OPF,0,34,"<"
CHRS OPF,0,33,"="
CHRS OPF,0,35,">"
CHRS OPF,"?","?","?"
CHRS OPF,0,140,"@"
XXZ←101
REPEAT =26,<CHRS LETF,0,XXZ+40,XXZ-40
XXZ←XXZ+1>
CHRS OPF,0,173,"["
CHRS OPF,0,"\","\"
CHRS OPF,0,175,"]"
CHRS OPF,0,"↑","↑"
CHRS OPF,0,"←","←"
CHRS OPF,100,140,140
XXZ←141
REPEAT =26,<CHRS LETF,XXZ-40,XXZ,XXZ-100
XXZ←XXZ+1>
CHRS OPF,"[",173,173+M37
CHRS OPF,":",174,174+M37
CHRS OPF,"3",175,175
CHRS OPF,{"]"},176,176+M37
CHRS OPF,"\",177,177
CHRS OPF,0,0,200
IFE STANSW,<LPTAB: REPEAT 11,<XWD 600000,.-LPTAB>
REPEAT 4,<.-LPTAB>
XWD 400000,.-LPTAB
REPEAT 22,<XWD 600000,.-LPTAB>
REPEAT 37,<XWD 400000,.-LPTAB>
XWD 600000,.-LPTAB
REPEAT 40,<XWD 400000,.-LPTAB>
REPEAT 40,<XWD 600000,.-LPTAB>>
IFN STANSW,<LPTAB: REPEAT 11,<XWD 400000,.-LPTAB>
REPEAT 4,<.-LPTAB>
REPEAT 13,<XWD 400000,.-LPTAB>
XWD 400000,137
XWD 400000,.-LPTAB
XWD 400000,136
REPEAT 45,<XWD 400000,.-LPTAB>
XWD 400000,140
REPEAT 33,<XWD 400000,.-LPTAB>
134
XWD 400000,.-LPTAB
XWD 400000,32
XWD 400000,30
XWD 400000,100
REPEAT 33,<XWD 400000,.-LPTAB>
XWD 400000,176
XWD 400000,175
XWD 400000,134
XWD 400000,174>
SUBTTL END OF SOS
XLIST ;DON'T LIST LITERALS
IFN TWOSGM,{
LIT
DEPHASE
END STPTA
;} END STPT